mark RFX boards as i_and_q_swapped
[debian/gnuradio] / usrp2 / fpga / control_lib / buffer_pool.v
1
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.
8
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)
13
14 module buffer_pool
15   (input wb_clk_i,
16    input wb_rst_i,
17    input wb_we_i,
18    input wb_stb_i,
19    input [15:0] wb_adr_i,
20    input [31:0] wb_dat_i,   
21    output [31:0] wb_dat_o,
22    output reg wb_ack_o,
23    output wb_err_o,
24    output wb_rty_o,
25    
26    input stream_clk,
27    input stream_rst,
28    
29    input set_stb, input [7:0] set_addr, input [31:0] set_data,
30    output [31:0] status,
31    output sys_int_o,
32
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,
35    
36    // Write Interfaces
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,
41    
42    // Read Interfaces
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
47    );
48
49    wire [7:0]    sel_a;
50    
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
53    
54    decoder_3_8 dec(.sel(which_buf),.res(sel_a));
55    
56    genvar        i;
57    
58    wire          go;
59
60    reg [2:0]     port[0:7];      
61    reg [3:0]     read_src[0:3];
62    reg [3:0]     write_src[0:3];
63    
64    wire [7:0]    done;
65    wire [7:0]    error;
66    wire [7:0]    idle;
67    
68    wire [31:0]   buf_doa[0:7];
69    
70    wire [7:0]    buf_enb;
71    wire [7:0]    buf_web;
72    wire [8:0]    buf_addrb[0:7];
73    wire [31:0]   buf_dib[0:7];
74    wire [31:0]   buf_dob[0:7];
75    
76    wire [31:0]   wr_dat_i[0:7];
77    wire [7:0]    wr_write_i;
78    wire [7:0]    wr_done_i;
79    wire [7:0]    wr_error_i;
80    wire [7:0]    wr_ready_o;
81    wire [7:0]    wr_full_o;
82    
83    wire [31:0]   rd_dat_o[0:7];
84    wire [7:0]    rd_read_i;
85    wire [7:0]    rd_done_i;
86    wire [7:0]    rd_error_i;
87    wire [7:0]    rd_sop_o;
88    wire [7:0]    rd_eop_o;
89    
90    assign        status = {8'd0,idle[7:0],error[7:0],done[7:0]};
91
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]};
100    
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));
105
106    integer       k;
107    always @(posedge stream_clk)
108      if(stream_rst)
109        for(k=0;k<8;k=k+1)
110          port[k] <= 4;   // disabled
111      else
112        for(k=0;k<8;k=k+1)
113          if(go & (fifo_ctrl[31:28]==k))
114            port[k] <= fifo_ctrl[27:25];
115
116    always @(posedge stream_clk)
117      if(stream_rst)
118        for(k=0;k<4;k=k+1)
119          read_src[k] <= 8;  // disabled
120      else
121        for(k=0;k<4;k=k+1)
122          if(go & fifo_ctrl[22] & (fifo_ctrl[27:25]==k))
123            read_src[k] <= fifo_ctrl[31:28];
124    
125    always @(posedge stream_clk)
126      if(stream_rst)
127        for(k=0;k<4;k=k+1)
128          write_src[k] <= 8;  // disabled
129      else
130        for(k=0;k<4;k=k+1)
131          if(go & fifo_ctrl[23] & (fifo_ctrl[27:25]==k))
132            write_src[k] <= fifo_ctrl[31:28];
133    
134    generate
135       for(i=0;i<8;i=i+1)
136         begin : gen_buffer
137            RAMB16_S36_S36 dpram
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]) );
142            
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])); */
148
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]),
153               .en_o(buf_enb[i]),
154               .we_o(buf_web[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]) 
170               );
171
172            // FIXME -- if it is a problem, maybe we don't need enables on these muxes
173            mux4 #(.WIDTH(32)) 
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]));
176            mux4 #(.WIDTH(1)) 
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]));
179            mux4 #(.WIDTH(1)) 
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]));
182            mux4 #(.WIDTH(1)) 
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]));
185            mux4 #(.WIDTH(1)) 
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]));
188            mux4 #(.WIDTH(1)) 
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]));
191            mux4 #(.WIDTH(1)) 
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
195    endgenerate
196
197    //----------------------------------------------------------------------
198    // Wishbone Outputs
199
200    // Use the following lines if ram output and mux can be made fast enough
201
202    assign wb_err_o = 1'b0;  // Unused for now
203    assign wb_rty_o = 1'b0;  // Unused for now
204    
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];
208
209    // Use this if we can't make the RAM+MUX fast enough
210    // reg [31:0] wb_dat_o_reg;
211    // reg             stb_d1;
212
213    // always @(posedge wb_clk_i)
214    //  begin
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);
218    //  end
219    //assign     wb_dat_o = wb_dat_o_reg;
220    
221    mux8 #(.WIDTH(1)) 
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));
225
226    mux8 #(.WIDTH(1)) 
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));
230    
231    mux8 #(.WIDTH(1)) 
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));
235
236    mux8 #(.WIDTH(1)) 
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));
240    
241    mux8 #(.WIDTH(1)) 
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));
245
246    mux8 #(.WIDTH(1)) 
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));
250    
251    mux8 #(.WIDTH(1)) 
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));
255    
256    mux8 #(.WIDTH(1)) 
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));
260    
261    mux8 #(.WIDTH(1)) 
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));
265    
266    mux8 #(.WIDTH(1)) 
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));
270    
271    mux8 #(.WIDTH(32))
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));
275    
276    mux8 #(.WIDTH(1)) 
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));
280    
281    mux8 #(.WIDTH(1)) 
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));
285    
286    mux8 #(.WIDTH(32))
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));
290    
291    mux8 #(.WIDTH(1)) 
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));
295    
296    mux8 #(.WIDTH(1)) 
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));
300    
301    mux8 #(.WIDTH(32))
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));
305    
306    mux8 #(.WIDTH(1)) 
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));
310    
311    mux8 #(.WIDTH(1)) 
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));
315    
316    mux8 #(.WIDTH(32))
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));
320    
321    assign sys_int_o = (|error) | (|done);
322    
323 endmodule // buffer_pool