blob: 5a110881c5220982a468d80ae6acba8db43233b2 [file] [log] [blame]
module WBAddressExtension (
input wire wb_clk_i,
input wire wb_rst_i,
// Wishbone Slave port from caravel
input wire wbs_cyc_i,
input wire wbs_stb_i,
input wire wbs_we_i,
input wire[3:0] wbs_sel_i,
input wire[31:0] wbs_adr_i,
input wire[31:0] wbs_data_i,
output reg wbs_ack_o,
output reg[31:0] wbs_data_o,
// Wishbone connection to user space
output wire userSpace_wb_cyc_i,
output wire userSpace_wb_stb_i,
output wire userSpace_wb_we_i,
output wire[3:0] userSpace_wb_sel_i,
output wire[31:0] userSpace_wb_adr_i,
output wire[31:0] userSpace_wb_data_i,
input wire userSpace_wb_ack_o,
input wire[31:0] userSpace_wb_data_o
);
reg[31:0] currentAddress = 32'b0;
// Connect user space wishbone bus
wire busAccess = wbs_cyc_i && wbs_adr_i[31:16] == 16'h3000;
wire userSpaceSelect = busAccess && wbs_adr_i[15];
wire[14:0] addressOffset = wbs_adr_i[14:0];
assign userSpace_wb_cyc_i = userSpaceSelect ? wbs_cyc_i : 1'b0;
assign userSpace_wb_stb_i = userSpaceSelect ? wbs_stb_i : 1'b0;
assign userSpace_wb_we_i = userSpaceSelect ? wbs_we_i : 1'b0;
assign userSpace_wb_sel_i = userSpaceSelect ? wbs_sel_i : 4'b0000;
assign userSpace_wb_adr_i = userSpaceSelect ? { currentAddress[31:15], addressOffset } : 32'b0;
assign userSpace_wb_data_i = userSpaceSelect ? wbs_data_i : 32'b0;
// Wishbone interface to allow setting current addres
localparam STATE_IDLE = 2'h0;
localparam STATE_WRITE_SINGLE = 2'h1;
localparam STATE_READ_SINGLE = 2'h2;
localparam STATE_FINISH = 2'h3;
reg[1:0] state = STATE_IDLE;
reg[3:0] currentByteSelect;
reg[31:0] currentDataIn;
reg acknowledge = 1'b0;
reg[31:0] dataRead_buffered = ~32'b0;
always @(posedge wb_clk_i) begin
if (wb_rst_i) begin
state <= STATE_IDLE;
acknowledge <= 1'b0;
dataRead_buffered <= ~32'b0;
end else begin
case (state)
STATE_IDLE: begin
acknowledge <= 1'b0;
dataRead_buffered <= ~32'b0;
if (wbs_cyc_i && busAccess && !userSpaceSelect) begin
if (wbs_stb_i) begin
if (wbs_we_i) begin
state <= STATE_WRITE_SINGLE;
end else begin
state <= STATE_READ_SINGLE;
end
end
end
end
STATE_WRITE_SINGLE: begin
state <= STATE_FINISH;
acknowledge <= 1'b1;
if (wbs_sel_i[0]) currentAddress[7:0] <= wbs_data_i[7:0];
if (wbs_sel_i[1]) currentAddress[15:8] <= wbs_data_i[15:8];
if (wbs_sel_i[2]) currentAddress[23:16] <= wbs_data_i[23:16];
if (wbs_sel_i[3]) currentAddress[31:24] <= wbs_data_i[31:24];
end
STATE_READ_SINGLE: begin
state <= STATE_FINISH;
acknowledge <= 1'b1;
dataRead_buffered <= currentAddress;
end
STATE_FINISH: begin
state <= STATE_IDLE;
acknowledge <= 1'b0;
dataRead_buffered <= ~32'b0;
end
default: begin
state <= STATE_IDLE;
acknowledge <= 1'b0;
end
endcase
end
end
// Connect wishbone return signals
always @(*) begin
if (busAccess) begin
if (userSpaceSelect) begin
wbs_ack_o <= userSpace_wb_ack_o;
wbs_data_o <= userSpace_wb_data_o;
end else begin
wbs_ack_o <= acknowledge;
wbs_data_o <= dataRead_buffered;
end
end else begin
wbs_ack_o <= 1'b0;
wbs_data_o <= 32'b0;
end
end
endmodule