2 // Buffer pool. Contains 8 buffers, each 2K (512 by 32). Each buffer
3 // is a dual-ported RAM. Port A on each of them is indirectly connected
4 // to the wishbone bus by a bridge. Port B may be connected any one of the
5 // 8 (4 rd, 4 wr) FIFO-like streaming interaces, or disconnected. The wishbone bus
6 // provides access to all 8 buffers, and also controls the connections
7 // between the ports and the buffers, allocating them as needed.
9 // wb_adr is 16 bits --
10 // bits 13:11 select which buffer
11 // bits 10:2 select line in buffer
12 // bits 1:0 are unused (32-bit access only)
19 input [15:0] wb_adr_i,
20 input [31:0] wb_dat_i,
21 output [31:0] wb_dat_o,
29 input set_stb, input [7:0] set_addr, input [31:0] set_data,
33 output [31:0] s0, output [31:0] s1, output [31:0] s2, output [31:0] s3,
34 output [31:0] s4, output [31:0] s5, output [31:0] s6, output [31:0] s7,
37 input [31:0] wr0_dat_i, input wr0_write_i, input wr0_done_i, input wr0_error_i, output wr0_ready_o, output wr0_full_o,
38 input [31:0] wr1_dat_i, input wr1_write_i, input wr1_done_i, input wr1_error_i, output wr1_ready_o, output wr1_full_o,
39 input [31:0] wr2_dat_i, input wr2_write_i, input wr2_done_i, input wr2_error_i, output wr2_ready_o, output wr2_full_o,
40 input [31:0] wr3_dat_i, input wr3_write_i, input wr3_done_i, input wr3_error_i, output wr3_ready_o, output wr3_full_o,
43 output [31:0] rd0_dat_o, input rd0_read_i, input rd0_done_i, input rd0_error_i, output rd0_sop_o, output rd0_eop_o,
44 output [31:0] rd1_dat_o, input rd1_read_i, input rd1_done_i, input rd1_error_i, output rd1_sop_o, output rd1_eop_o,
45 output [31:0] rd2_dat_o, input rd2_read_i, input rd2_done_i, input rd2_error_i, output rd2_sop_o, output rd2_eop_o,
46 output [31:0] rd3_dat_o, input rd3_read_i, input rd3_done_i, input rd3_error_i, output rd3_sop_o, output rd3_eop_o
51 wire [2:0] which_buf = wb_adr_i[13:11]; // address 15:14 selects the buffer pool
52 wire [8:0] buf_addra = wb_adr_i[10:2]; // ignore address 1:0, 32-bit access only
54 decoder_3_8 dec(.sel(which_buf),.res(sel_a));
61 reg [3:0] read_src[0:3];
62 reg [3:0] write_src[0:3];
68 wire [31:0] buf_doa[0:7];
72 wire [8:0] buf_addrb[0:7];
73 wire [31:0] buf_dib[0:7];
74 wire [31:0] buf_dob[0:7];
76 wire [31:0] wr_dat_i[0:7];
77 wire [7:0] wr_write_i;
79 wire [7:0] wr_error_i;
80 wire [7:0] wr_ready_o;
83 wire [31:0] rd_dat_o[0:7];
86 wire [7:0] rd_error_i;
90 assign status = {8'd0,idle[7:0],error[7:0],done[7:0]};
92 assign s0 = {23'd0,buf_addrb[0]};
93 assign s1 = {23'd0,buf_addrb[1]};
94 assign s2 = {23'd0,buf_addrb[2]};
95 assign s3 = {23'd0,buf_addrb[3]};
96 assign s4 = {23'd0,buf_addrb[4]};
97 assign s5 = {23'd0,buf_addrb[5]};
98 assign s6 = {23'd0,buf_addrb[6]};
99 assign s7 = {23'd0,buf_addrb[7]};
101 wire [31:0] fifo_ctrl;
102 setting_reg #(.my_addr(64))
103 sreg(.clk(stream_clk),.rst(stream_rst),.strobe(set_stb),.addr(set_addr),.in(set_data),
104 .out(fifo_ctrl),.changed(go));
107 always @(posedge stream_clk)
110 port[k] <= 4; // disabled
113 if(go & (fifo_ctrl[31:28]==k))
114 port[k] <= fifo_ctrl[27:25];
116 always @(posedge stream_clk)
119 read_src[k] <= 8; // disabled
122 if(go & fifo_ctrl[22] & (fifo_ctrl[27:25]==k))
123 read_src[k] <= fifo_ctrl[31:28];
125 always @(posedge stream_clk)
128 write_src[k] <= 8; // disabled
131 if(go & fifo_ctrl[23] & (fifo_ctrl[27:25]==k))
132 write_src[k] <= fifo_ctrl[31:28];
138 (.DOA(buf_doa[i]),.ADDRA(buf_addra),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0),
139 .ENA(wb_stb_i & sel_a[i]),.SSRA(0),.WEA(wb_we_i),
140 .DOB(buf_dob[i]),.ADDRB(buf_addrb[i]),.CLKB(stream_clk),.DIB(buf_dib[i]),.DIPB(4'h0),
141 .ENB(buf_enb[i]),.SSRB(0),.WEB(buf_web[i]) );
143 /* ram_2port #(.DWIDTH(32),.AWIDTH(9)) buffer
144 (.clka(wb_clk_i),.ena(wb_stb_i & sel_a[i]),.wea(wb_we_i),
145 .addra(buf_addra),.dia(wb_dat_i),.doa(buf_doa[i]),
146 .clkb(stream_clk),.enb(buf_enb[i]),.web(buf_web[i]),
147 .addrb(buf_addrb[i]),.dib(buf_dib[i]),.dob(buf_dob[i])); */
149 buffer_int #(.BUFF_NUM(i)) fifo_int
150 (.clk(stream_clk),.rst(stream_rst),
151 .ctrl_word(fifo_ctrl),.go(go & (fifo_ctrl[31:28]==i)),
152 .done(done[i]),.error(error[i]),.idle(idle[i]),
155 .addr_o(buf_addrb[i]),
156 .dat_to_buf(buf_dib[i]),
157 .dat_from_buf(buf_dob[i]),
158 .wr_dat_i(wr_dat_i[i]),
159 .wr_write_i(wr_write_i[i]),
160 .wr_done_i(wr_done_i[i]),
161 .wr_error_i(wr_error_i[i]),
162 .wr_ready_o(wr_ready_o[i]),
163 .wr_full_o(wr_full_o[i]),
164 .rd_dat_o(rd_dat_o[i]),
165 .rd_read_i(rd_read_i[i]),
166 .rd_done_i(rd_done_i[i]),
167 .rd_error_i(rd_error_i[i]),
168 .rd_sop_o(rd_sop_o[i]),
169 .rd_eop_o(rd_eop_o[i])
172 // FIXME -- if it is a problem, maybe we don't need enables on these muxes
174 mux4_dat_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_dat_i),.i1(wr1_dat_i),
175 .i2(wr2_dat_i),.i3(wr3_dat_i),.o(wr_dat_i[i]));
177 mux4_write_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_write_i),.i1(wr1_write_i),
178 .i2(wr2_write_i),.i3(wr3_write_i),.o(wr_write_i[i]));
180 mux4_wrdone_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_done_i),.i1(wr1_done_i),
181 .i2(wr2_done_i),.i3(wr3_done_i),.o(wr_done_i[i]));
183 mux4_wrerror_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_error_i),.i1(wr1_error_i),
184 .i2(wr2_error_i),.i3(wr3_error_i),.o(wr_error_i[i]));
186 mux4_read_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_read_i),.i1(rd1_read_i),
187 .i2(rd2_read_i),.i3(rd3_read_i),.o(rd_read_i[i]));
189 mux4_rddone_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_done_i),.i1(rd1_done_i),
190 .i2(rd2_done_i),.i3(rd3_done_i),.o(rd_done_i[i]));
192 mux4_rderror_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_error_i),.i1(rd1_error_i),
193 .i2(rd2_error_i),.i3(rd3_error_i),.o(rd_error_i[i]));
194 end // block: gen_buffer
197 //----------------------------------------------------------------------
200 // Use the following lines if ram output and mux can be made fast enough
202 assign wb_err_o = 1'b0; // Unused for now
203 assign wb_rty_o = 1'b0; // Unused for now
205 always @(posedge wb_clk_i)
206 wb_ack_o <= wb_stb_i & ~wb_ack_o;
207 assign wb_dat_o = buf_doa[which_buf];
209 // Use this if we can't make the RAM+MUX fast enough
210 // reg [31:0] wb_dat_o_reg;
213 // always @(posedge wb_clk_i)
215 // wb_dat_o_reg <= buf_doa[which_buf];
216 // stb_d1 <= wb_stb_i;
217 // wb_ack_o <= (stb_d1 & ~wb_ack_o) | (wb_we_i & wb_stb_i);
219 //assign wb_dat_o = wb_dat_o_reg;
222 mux8_wr_ready0(.en(~write_src[0][3]),.sel(write_src[0][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]),
223 .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]),
224 .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr0_ready_o));
227 mux8_wr_full0(.en(~write_src[0][3]),.sel(write_src[0][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]),
228 .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]),
229 .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr0_full_o));
232 mux8_wr_ready1(.en(~write_src[1][3]),.sel(write_src[1][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]),
233 .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]),
234 .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr1_ready_o));
237 mux8_wr_full1(.en(~write_src[1][3]),.sel(write_src[1][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]),
238 .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]),
239 .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr1_full_o));
242 mux8_wr_ready2(.en(~write_src[2][3]),.sel(write_src[2][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]),
243 .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]),
244 .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr2_ready_o));
247 mux8_wr_full2(.en(~write_src[2][3]),.sel(write_src[2][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]),
248 .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]),
249 .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr2_full_o));
252 mux8_wr_ready3(.en(~write_src[3][3]),.sel(write_src[3][2:0]), .i0(wr_ready_o[0]), .i1(wr_ready_o[1]),
253 .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), .i4(wr_ready_o[4]),
254 .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]),.o(wr3_ready_o));
257 mux8_wr_full3(.en(~write_src[3][3]),.sel(write_src[3][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]),
258 .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]),
259 .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr3_full_o));
262 mux8_rd_sop0(.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]),
263 .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]),
264 .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd0_sop_o));
267 mux8_rd_eop0(.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]),
268 .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]),
269 .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd0_eop_o));
272 mux8_rd_dat_0 (.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]),
273 .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]),
274 .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd0_dat_o));
277 mux8_rd_sop1(.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]),
278 .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]),
279 .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd1_sop_o));
282 mux8_rd_eop1(.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]),
283 .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]),
284 .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd1_eop_o));
287 mux8_rd_dat_1 (.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]),
288 .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]),
289 .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd1_dat_o));
292 mux8_rd_sop2(.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]),
293 .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]),
294 .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd2_sop_o));
297 mux8_rd_eop2(.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]),
298 .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]),
299 .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd2_eop_o));
302 mux8_rd_dat_2 (.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]),
303 .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]),
304 .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd2_dat_o));
307 mux8_rd_sop3(.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]),
308 .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]),
309 .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd3_sop_o));
312 mux8_rd_eop3(.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]),
313 .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]),
314 .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd3_eop_o));
317 mux8_rd_dat_3 (.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_dat_o[0]), .i1(rd_dat_o[1]),
318 .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]),
319 .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd3_dat_o));
321 assign sys_int_o = (|error) | (|done);
323 endmodule // buffer_pool