Line 1... |
Line 1... |
module ram_wb ( dat_i, dat_o, adr_i, we_i, sel_i, cyc_i, stb_i, ack_o, cti_i, clk_i, rst_i);
|
module ram_wb
|
|
(
|
|
// Inputs
|
|
wbm0_adr_i, wbm0_bte_i, wbm0_cti_i, wbm0_cyc_i, wbm0_dat_i, wbm0_sel_i,
|
|
wbm0_stb_i, wbm0_we_i,
|
|
// Outputs
|
|
wbm0_ack_o, wbm0_err_o, wbm0_rty_o, wbm0_dat_o,
|
|
|
|
// Inputs
|
|
wbm1_adr_i, wbm1_bte_i, wbm1_cti_i, wbm1_cyc_i, wbm1_dat_i, wbm1_sel_i,
|
|
wbm1_stb_i, wbm1_we_i,
|
|
// Outputs
|
|
wbm1_ack_o, wbm1_err_o, wbm1_rty_o, wbm1_dat_o,
|
|
|
parameter dat_width = 32;
|
// Clock, reset
|
parameter adr_width = 12;
|
wb_clk_i, wb_rst_i
|
parameter mem_size = 262144; // Default is 1MB (262144 32-bit words)
|
);
|
|
// Bus parameters
|
// wishbone signals
|
parameter dw = 32;
|
input [31:0] dat_i;
|
parameter aw = 32;
|
output [31:0] dat_o;
|
// Memory parameters
|
input [adr_width-1:2] adr_i;
|
parameter mem_span = 32'h0000_0400;
|
input we_i;
|
parameter adr_width_for_span = 11; //(log2(mem_span));
|
input [3:0] sel_i;
|
|
input cyc_i;
|
|
input stb_i;
|
input [aw-1:0] wbm0_adr_i;
|
output reg ack_o;
|
input [1:0] wbm0_bte_i;
|
input [2:0] cti_i;
|
input [2:0] wbm0_cti_i;
|
|
input wbm0_cyc_i;
|
// clock
|
input [dw-1:0] wbm0_dat_i;
|
input clk_i;
|
input [3:0] wbm0_sel_i;
|
// async reset
|
input wbm0_stb_i;
|
input rst_i;
|
input wbm0_we_i;
|
|
|
wire [31:0] wr_data;
|
output wbm0_ack_o;
|
|
output wbm0_err_o;
|
// mux for data to ram
|
output wbm0_rty_o;
|
assign wr_data[31:24] = sel_i[3] ? dat_i[31:24] : dat_o[31:24];
|
output [dw-1:0] wbm0_dat_o;
|
assign wr_data[23:16] = sel_i[2] ? dat_i[23:16] : dat_o[23:16];
|
|
assign wr_data[15: 8] = sel_i[1] ? dat_i[15: 8] : dat_o[15: 8];
|
input [aw-1:0] wbm1_adr_i;
|
assign wr_data[ 7: 0] = sel_i[0] ? dat_i[ 7: 0] : dat_o[ 7: 0];
|
input [1:0] wbm1_bte_i;
|
|
input [2:0] wbm1_cti_i;
|
|
input wbm1_cyc_i;
|
|
input [dw-1:0] wbm1_dat_i;
|
|
input [3:0] wbm1_sel_i;
|
|
input wbm1_stb_i;
|
|
input wbm1_we_i;
|
|
|
|
output wbm1_ack_o;
|
|
output wbm1_err_o;
|
|
output wbm1_rty_o;
|
|
output [dw-1:0] wbm1_dat_o;
|
|
|
|
|
|
input wb_clk_i;
|
|
input wb_rst_i;
|
|
|
|
// Internal wires to actual RAM
|
|
wire [aw-1:0] wb_ram_adr_i;
|
|
wire [1:0] wb_ram_bte_i;
|
|
wire [2:0] wb_ram_cti_i;
|
|
wire wb_ram_cyc_i;
|
|
wire [dw-1:0] wb_ram_dat_i;
|
|
wire [3:0] wb_ram_sel_i;
|
|
wire wb_ram_stb_i;
|
|
wire wb_ram_we_i;
|
|
|
|
wire wb_ram_ack_o;
|
|
wire wb_ram_err_o;
|
|
wire wb_ram_rty_o;
|
|
wire [dw-1:0] wb_ram_dat_o;
|
|
|
|
reg [1:0] input_select, last_selected;
|
|
wire arb_for_wbm0, arb_for_wbm1;
|
|
// Wires allowing selection of new input
|
|
assign arb_for_wbm0 = (last_selected[1] | !wbm1_cyc_i) & !(|input_select);
|
|
assign arb_for_wbm1 = (last_selected[0] | !wbm0_cyc_i) & !(|input_select);
|
|
|
|
// Master select logic
|
|
always @(posedge wb_clk_i)
|
|
if (wb_rst_i)
|
|
input_select <= 0;
|
|
else if ((input_select[0] & !wbm0_cyc_i) | (input_select[1] & !wbm1_cyc_i))
|
|
input_select <= 0;
|
|
else if (!(&input_select) & wbm0_cyc_i & arb_for_wbm0)
|
|
input_select <= 2'b01;
|
|
else if (!(&input_select) & wbm1_cyc_i & arb_for_wbm1)
|
|
input_select <= 2'b10;
|
|
|
|
always @(posedge wb_clk_i)
|
|
if (wb_rst_i)
|
|
last_selected <= 0;
|
|
else if (!(&input_select) & wbm0_cyc_i & arb_for_wbm0)
|
|
last_selected <= 2'b01;
|
|
else if (!(&input_select) & wbm1_cyc_i & arb_for_wbm1)
|
|
last_selected <= 2'b10;
|
|
|
|
// Mux input signals to RAM (default to wbm0)
|
|
assign wb_ram_adr_i = (input_select[1]) ? wbm1_adr_i :
|
|
(input_select[0]) ? wbm0_adr_i : 0;
|
|
assign wb_ram_bte_i = (input_select[1]) ? wbm1_bte_i :
|
|
(input_select[0]) ? wbm0_bte_i : 0;
|
|
assign wb_ram_cti_i = (input_select[1]) ? wbm1_cti_i :
|
|
(input_select[0]) ? wbm0_cti_i : 0;
|
|
assign wb_ram_cyc_i = (input_select[1]) ? wbm1_cyc_i :
|
|
(input_select[0]) ? wbm0_cyc_i : 0;
|
|
assign wb_ram_dat_i = (input_select[1]) ? wbm1_dat_i :
|
|
(input_select[0]) ? wbm0_dat_i : 0;
|
|
assign wb_ram_sel_i = (input_select[1]) ? wbm1_sel_i :
|
|
(input_select[0]) ? wbm0_sel_i : 0;
|
|
assign wb_ram_stb_i = (input_select[1]) ? wbm1_stb_i :
|
|
(input_select[0]) ? wbm0_stb_i : 0;
|
|
assign wb_ram_we_i = (input_select[1]) ? wbm1_we_i :
|
|
(input_select[0]) ? wbm0_we_i : 0;
|
|
|
|
// Output from RAM, gate the ACK, ERR, RTY signals appropriately
|
|
assign wbm0_dat_o = wb_ram_dat_o;
|
|
assign wbm0_ack_o = wb_ram_ack_o & input_select[0];
|
|
assign wbm0_err_o = wb_ram_err_o & input_select[0];
|
|
assign wbm0_rty_o = wb_ram_rty_o & input_select[0];
|
|
|
|
assign wbm1_dat_o = wb_ram_dat_o;
|
|
assign wbm1_ack_o = wb_ram_ack_o & input_select[1];
|
|
assign wbm1_err_o = wb_ram_err_o & input_select[1];
|
|
assign wbm1_rty_o = wb_ram_rty_o & input_select[1];
|
|
|
ram_wb_sc_sw
|
ram_wb_b3 ram_wb_b3_0
|
#
|
|
(
|
(
|
.dat_width(dat_width),
|
// Outputs
|
.adr_width(adr_width),
|
.wb_ack_o (wb_ram_ack_o),
|
.mem_size(mem_size)
|
.wb_err_o (wb_ram_err_o),
|
)
|
.wb_rty_o (wb_ram_rty_o),
|
ram0
|
.wb_dat_o (wb_ram_dat_o),
|
(
|
// Inputs
|
.dat_i(wr_data),
|
.wb_adr_i (wb_ram_adr_i),
|
.dat_o(dat_o),
|
.wb_bte_i (wb_ram_bte_i),
|
.adr_i({2'b00, adr_i}),
|
.wb_cti_i (wb_ram_cti_i),
|
.we_i(we_i & ack_o),
|
.wb_cyc_i (wb_ram_cyc_i),
|
.clk(clk_i)
|
.wb_dat_i (wb_ram_dat_i),
|
);
|
.wb_sel_i (wb_ram_sel_i),
|
|
.wb_stb_i (wb_ram_stb_i),
|
|
.wb_we_i (wb_ram_we_i),
|
|
.wb_clk_i (wb_clk_i),
|
|
.wb_rst_i (wb_rst_i));
|
|
|
|
defparam ram_wb_b3_0.aw = aw;
|
|
defparam ram_wb_b3_0.dw = dw;
|
|
defparam ram_wb_b3_0.mem_span = mem_span;
|
|
defparam ram_wb_b3_0.adr_width_for_span = adr_width_for_span;
|
|
|
// ack_o
|
endmodule // ram_wb
|
always @ (posedge clk_i or posedge rst_i)
|
|
if (rst_i)
|
|
ack_o <= 1'b0;
|
|
else
|
|
if (!ack_o)
|
|
begin
|
|
if (cyc_i & stb_i)
|
|
ack_o <= 1'b1;
|
|
end
|
|
else
|
|
ack_o <= 1'b0;
|
|
|
|
// We did have acking logic which was sensitive to the
|
|
// burst signals, cti_i, but this proved to cause problems
|
|
// and we were never receiving back-to-back reads or writes
|
|
// anyway. This logic which only acks one transaction at a
|
|
// time appears to work well, despite not supporting burst
|
|
// transactions.
|
|
|
|
endmodule
|
|
|
|
|
|
No newline at end of file
|
No newline at end of file
|