diff options
| -rw-r--r-- | control_lib/newfifo/buffer_int.v | 168 | ||||
| -rw-r--r-- | control_lib/newfifo/buffer_int_tb.v | 418 | ||||
| -rw-r--r-- | control_lib/newfifo/buffer_pool.v | 283 | ||||
| -rw-r--r-- | control_lib/newfifo/buffer_pool_tb.v | 58 | 
4 files changed, 927 insertions, 0 deletions
| diff --git a/control_lib/newfifo/buffer_int.v b/control_lib/newfifo/buffer_int.v new file mode 100644 index 000000000..b45ed3532 --- /dev/null +++ b/control_lib/newfifo/buffer_int.v @@ -0,0 +1,168 @@ + +// FIFO Interface to the 2K buffer RAMs +// Read port is read-acknowledge +// FIXME do we want to be able to interleave reads and writes? + +module buffer_int +  #(parameter BUF_NUM = 0, +    parameter BUF_SIZE = 9) +    (// Control Interface +     input clk, +     input rst, +     input [31:0] ctrl_word, +     input go, +     output done, +     output error, +     output idle, +     output [1:0] flag, +      +     // Buffer Interface +     output en_o, +     output we_o, +     output reg [BUF_SIZE-1:0] addr_o, +     output [31:0] dat_to_buf, +     input [31:0] dat_from_buf, +      +     // Write FIFO Interface +     input [31:0] wr_data_i, +     input [3:0] wr_flags_i, +     input wr_ready_i, +     output wr_ready_o, +      +     // Read FIFO Interface +     output [31:0] rd_data_o, +     output [3:0] rd_flags_o, +     output rd_ready_o, +     input rd_ready_i +     ); +    +   reg [31:0] ctrl_reg; +   reg 	      go_reg; +    +   always @(posedge clk) +     go_reg <= go; +    +   always @(posedge clk) +     if(rst) +       ctrl_reg <= 0; +     else +       if(go & (ctrl_word[31:28] == BUF_NUM)) +	 ctrl_reg <= ctrl_word; +    +   wire [BUF_SIZE-1:0] firstline = ctrl_reg[BUF_SIZE-1:0]; +   wire [BUF_SIZE-1:0] lastline = ctrl_reg[2*BUF_SIZE-1:BUF_SIZE]; + +   wire       read = ctrl_reg[22]; +   wire       write = ctrl_reg[23]; +   wire       clear = ctrl_reg[24]; +   //wire [2:0] port = ctrl_reg[27:25];  // Ignored in this block +   //wire [3:0] buff_num = ctrl_reg[31:28];  // Ignored here ? +    +   localparam IDLE = 3'd0; +   localparam PRE_READ = 3'd1; +   localparam READING = 3'd2; +   localparam WRITING = 3'd3; +   localparam ERROR = 3'd4; +   localparam DONE = 3'd5; +    +   reg [2:0]  state; +   reg 	      rd_sop, rd_eop; +   wire       wr_sop, wr_eop, wr_error; +   reg [1:0]  rd_occ; +   wire [1:0] wr_occ; +    +   always @(posedge clk) +     if(rst) +       begin +	  state <= IDLE; +	  rd_sop <= 0; +	  rd_eop <= 0; +	  rd_occ <= 0; +       end +     else +       if(clear) +	 begin +	    state <= IDLE; +	    rd_sop <= 0; +	    rd_eop <= 0; +	    rd_occ <= 0; +	 end +       else  +	 case(state) +	   IDLE : +	     if(go_reg & read) +	       begin +		  addr_o <= firstline; +		  state <= PRE_READ; +	       end +	     else if(go_reg & write) +	       begin +		  addr_o <= firstline; +		  state <= WRITING; +	       end +	    +	   PRE_READ : +	     begin +		state <= READING; +		addr_o <= addr_o + 1; +		rd_occ <= 2'b00; +		rd_sop <= 1; +		rd_eop <= 0; +	     end +	    +	   READING : +	     if(rd_ready_i) +	       begin +		  rd_sop <= 0; +		  addr_o <= addr_o + 1; +		  if(addr_o == lastline) +		    begin +		       rd_eop <= 1; +		       // FIXME assign occ here +		       rd_occ <= 0; +		    end +		  else +		    rd_eop <= 0; +		  if(rd_eop) +		    state <= DONE; +	       end +	    +	   WRITING : +	     begin +		if(wr_ready_i) +		  begin +		     addr_o <= addr_o + 1; +		     if(wr_error) +		       begin +			  state <= ERROR; +			  // Save OCC flags here +		       end +		     else if((addr_o == lastline)||wr_eop) +		       state <= DONE; +		  end // if (wr_ready_i) +	     end // case: WRITING +	    +	 endcase // case(state) +    +   assign     dat_to_buf = wr_data_i; +   assign     rd_data_o = dat_from_buf; + +   assign     rd_flags_o = { rd_occ[1:0], rd_eop, rd_sop }; +   assign     rd_ready_o = (state == READING); +    +   assign     wr_sop = wr_flags_i[0]; +   assign     wr_eop = wr_flags_i[1]; +   assign     wr_occ = wr_flags_i[3:2]; +   assign     wr_error = wr_sop & wr_eop; +   assign     wr_ready_o = (state == WRITING); + +   assign     we_o = (state == WRITING); +   //assign     we_o = (state == WRITING) && wr_ready_i;  // always write to avoid timing issue + +   assign     en_o = ~((state==READING)& ~rd_ready_i);   // FIXME potential critical path +    +   assign     done = (state == DONE); +   assign     error = (state == ERROR); +   assign     idle = (state == IDLE); + +endmodule // buffer_int diff --git a/control_lib/newfifo/buffer_int_tb.v b/control_lib/newfifo/buffer_int_tb.v new file mode 100644 index 000000000..df54dcc0b --- /dev/null +++ b/control_lib/newfifo/buffer_int_tb.v @@ -0,0 +1,418 @@ + +module buffer_int_tb (); + +   reg clk = 0; +   reg rst = 1; + +   initial #100 rst = 0; +   always #5 clk = ~clk; + +   wire en, we; +   wire [8:0] addr; +   wire [31:0] fifo2buf, buf2fifo; +    +   wire [31:0] rd_data_o; +   wire [3:0]  rd_flags_o; +   wire        rd_sop_o, rd_eop_o; +   reg 	       rd_error_i = 0, rd_read_i = 0; +    +   reg [31:0]  wr_data_i = 0; +   wire [3:0]  wr_flags_i; +   reg 	       wr_eop_i = 0, wr_sop_i = 0; +   reg 	       wr_write_i = 0; +   wire        wr_ready_o, wr_full_o; +    +   reg 	       clear = 0, write = 0, read = 0; +   reg [8:0]   firstline = 0, lastline = 0; +   wire [3:0]  step = 1; +   wire [31:0] ctrl_word = {4'b0,3'b0,clear,write,read,step,lastline,firstline}; +   reg 	       go = 0; +   wire        done, error; + +   assign      wr_flags_i = {2'b00, wr_eop_i, wr_sop_i}; +   assign      rd_sop_o = rd_flags_o[0]; +   assign      rd_eop_o = rd_flags_o[1]; +    +   buffer_int buffer_int +     (.clk(clk),.rst(rst), +      .ctrl_word(ctrl_word),.go(go), +      .done(done),.error(error), +       +      // Buffer Interface +      .en_o(en),.we_o(we),.addr_o(addr), +      .dat_to_buf(fifo2buf),.dat_from_buf(buf2fifo), + +      // Write FIFO Interface +      .wr_data_i(wr_data_i), .wr_flags_i(wr_flags_i), .wr_write_i(wr_write_i), .wr_ready_o(wr_ready_o), + +      // Read FIFO Interface +      .rd_data_o(rd_data_o), .rd_flags_o(rd_flags_o), .rd_ready_o(rd_ready_o), .rd_read_i(rd_read_i) +      ); +    +   reg 	       ram_en = 0, ram_we = 0; +   reg [8:0]   ram_addr = 0; +   reg [31:0]  ram_data = 0; +    +   ram_2port #(.DWIDTH(32),.AWIDTH(9)) ram_2port +     (.clka(clk), .ena(ram_en), .wea(ram_we), .addra(ram_addr), .dia(ram_data), .doa(), +      .clkb(clk), .enb(en), .web(we), .addrb(addr), .dib(fifo2buf), .dob(buf2fifo) ); +    +   initial +     begin +	@(negedge rst); +	@(posedge clk); +	FillRAM; + +	ResetBuffer; +	SetBufferRead(5,10); +	$display("Testing full read, no wait states."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(6,0); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(5,10); +	$display("Testing full read, 2 wait states."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(6,2); +	repeat (10) +	  @(posedge clk); + +	ResetBuffer; +	SetBufferRead(5,10); +	$display("Testing partial read, 0 wait states, then nothing after last."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(3,0); +	repeat (10) +	  @(posedge clk); + +	ResetBuffer; +	SetBufferRead(5,10); +	$display("Testing partial read, 0 wait states, then done at same time as last."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(2,0); +	ReadALine; +	repeat (10) +	  @(posedge clk); + +	ResetBuffer; +	SetBufferRead(5,10); +	$display("Testing partial read, 3 wait states, then error at same time as last."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(2,3); +	rd_error_i <= 1; +	ReadALine; +	rd_error_i <= 0; +	repeat (10) +	  @(posedge clk); + +	ResetBuffer; +	SetBufferRead(500,511); +	$display("Testing full read, to the end of the buffer."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(12,0); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(0,511); +	$display("Testing full read, start to end of the buffer."); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(512,0); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(505,3); +	$display("Testing full read, wraparound"); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(11,0); +	repeat (10) +	  @(posedge clk); + +	ResetBuffer; +	SetBufferWrite(10,15); +	$display("Testing Full Write, no wait states"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(6,0,72); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferWrite(18,23); +	$display("Testing Full Write, 1 wait states"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(6,1,101); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferWrite(27,40); +	$display("Testing Partial Write, 0 wait states"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(6,0,201); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferWrite(45,200); +	$display("Testing Partial Write, 0 wait states, then done and write simultaneously"); +	while(!wr_ready_o) +	  @(posedge clk); +	wr_sop_i <= 1; wr_eop_i <= 0; +	WriteLines(6,0,301); +	wr_sop_i <= 0; wr_eop_i <= 1; +	WriteALine(400); +	wr_sop_i <= 0; wr_eop_i <= 0; +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferWrite(55,200); +	$display("Testing Partial Write, 0 wait states, then error"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(6,0,501); +	wr_sop_i <= 1; wr_eop_i <= 1; +	WriteALine(400); +	@(posedge clk); +	repeat (10) +	  @(posedge clk); +	wr_sop_i <= 0; wr_eop_i <= 0; +	 +	ResetBuffer; +	SetBufferRead(0,82); +	$display("Testing read after all the writes"); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(83,0); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferWrite(508,4); +	$display("Testing wraparound write"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(9,0,601); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(506,10); +	$display("Reading wraparound write"); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(17,0); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferWrite(0,511); +	$display("Testing Whole Buffer write"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(512,0,1000); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(0,511); +	$display("Reading Whole Buffer write"); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(512,0); +	repeat (10) +	  @(posedge clk); + +	/* +	ResetBuffer; +	SetBufferWrite(5,10); +	$display("Testing Write Too Many"); +	while(!wr_ready_o) +	  @(posedge clk); +	WriteLines(12,0,2000); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(0,15); +	$display("Reading back Write Too Many"); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(16,0); +	repeat (10) +	  @(posedge clk); +	*/ +	ResetBuffer; +	SetBufferWrite(15,20); +	$display("Testing Write One Less Than Full"); +	while(!wr_ready_o) +	  @(posedge clk); +	wr_sop_i <= 1; wr_eop_i <= 0; +	WriteALine(400); +	wr_sop_i <= 0; wr_eop_i <= 0; +	WriteLines(3,0,2000); +	wr_sop_i <= 0; wr_eop_i <= 1; +	WriteALine(400); +	wr_sop_i <= 0; wr_eop_i <= 0; +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	SetBufferRead(13,22); +	$display("Reading back Write One Less Than Full"); +	while(!rd_sop_o) +	  @(posedge clk); +	ReadLines(10,0); +	repeat (10) +	  @(posedge clk); +	 +	ResetBuffer; +	repeat(100) +	  @(posedge clk); +	$finish; +     end +    +   always @(posedge clk) +     if(rd_read_i == 1'd1) +       $display("READ Buffer %d, rd_sop_o %d, rd_eop_o %d", rd_data_o, rd_sop_o, rd_eop_o); + +   always @(posedge clk) +     if(wr_write_i == 1'd1) +       $display("WRITE Buffer %d,  wr_ready_o %d, wr_full_o %d", wr_data_i, wr_ready_o, wr_full_o); +	    +   initial begin +      $dumpfile("buffer_int_tb.lxt"); +      $dumpvars(0,buffer_int_tb); +   end + +   task FillRAM; +      begin +	 ram_addr <= 0; +	 ram_data <= 0; +	 @(posedge clk); +	 ram_en <= 1; +	 ram_we <= 1; +	 @(posedge clk); +	 repeat (511) +	   begin +	      ram_addr <= ram_addr + 1; +	      ram_data <= ram_data + 1; +	      ram_en <= 1; +	      ram_we <= 1; +	      @(posedge clk); +	   end +	 ram_en <= 0; +	 ram_we <= 0; +	 @(posedge clk); +	 $display("Filled the RAM"); +      end +   endtask // FillRAM + +   task ResetBuffer; +      begin +	 clear <= 1; read <= 0; write <= 0; +	 go <= 1; +	 @(posedge clk); +	 go <= 0; +	 @(posedge clk); +	 $display("Buffer Reset"); +      end +   endtask // ClearBuffer +    +   task SetBufferWrite; +      input [8:0] start; +      input [8:0] stop; +      begin +	 clear <= 0; read <= 0; write <= 1; +	 firstline <= start; +	 lastline <= stop; +	 go <= 1; +	 @(posedge clk); +	 go <= 0; +	 @(posedge clk); +	 $display("Buffer Set for Write"); +      end +   endtask // SetBufferWrite +    +   task SetBufferRead; +      input [8:0] start; +      input [8:0] stop; +      begin +	 clear <= 0; read <= 1; write <= 0; +	 firstline <= start; +	 lastline <= stop; +	 go <= 1; +	 @(posedge clk); +	 go <= 0; +	 @(posedge clk); +	 $display("Buffer Set for Read"); +      end +   endtask // SetBufferRead + +   task ReadALine; +      begin +	 while(~rd_ready_o) +	   @(posedge clk); +	 #1 rd_read_i <= 1; +	 @(posedge clk); +	 rd_read_i <= 0; +      end +   endtask // ReadALine + +   task ReadLines; +      input [9:0] lines; +      input [7:0] wait_states; +      begin +	 $display("Read Lines: Number %d, Wait States %d",lines,wait_states); +	 repeat (lines) +	   begin +	      ReadALine; +	      repeat (wait_states) +		@(posedge clk); +	   end +      end +   endtask // ReadLines +    +   task WriteALine; +      input [31:0] value; +      begin +	 while(~wr_ready_o) +	   @(posedge clk); +	 #1 wr_write_i <= 1; +	 wr_data_i <= value; +	 @(posedge clk); +	 wr_write_i <= 0; +      end +   endtask // WriteALine +    +   task WriteLines; +      input [9:0] lines; +      input [7:0] wait_states; +      input [31:0] value; +      begin +	 $display("Write Lines: Number %d, Wait States %d",lines,wait_states); +	 repeat(lines) +	   begin +	      value <= value + 1; +	      WriteALine(value); +	      repeat(wait_states) +		@(posedge clk); +	   end +      end +   endtask // WriteLines +    +endmodule // buffer_int_tb diff --git a/control_lib/newfifo/buffer_pool.v b/control_lib/newfifo/buffer_pool.v new file mode 100644 index 000000000..41ac1deb3 --- /dev/null +++ b/control_lib/newfifo/buffer_pool.v @@ -0,0 +1,283 @@ + +// Buffer pool.  Contains 8 buffers, each 2K (512 by 32).  Each buffer +// is a dual-ported RAM.  Port A on each of them is indirectly connected  +// to the wishbone bus by a bridge.  Port B may be connected any one of the +// 8 (4 rd, 4 wr) FIFO-like streaming interaces, or disconnected.  The wishbone bus +// provides access to all 8 buffers, and also controls the connections +// between the ports and the buffers, allocating them as needed. + +// wb_adr is 16 bits --  +//  bits 13:11 select which buffer +//  bits 10:2 select line in buffer +//  bits 1:0 are unused (32-bit access only) + +// BUF_SIZE is in address lines (i.e. log2 of number of lines).   +// For S3 it should be 9 (512 words, 2KB) +// For V5 it should be at least 10 (1024 words, 4KB) or 11 (2048 words, 8KB) + +module buffer_pool +  #(parameter BUF_SIZE = 9, +    parameter SET_ADDR = 64) +    (input wb_clk_i, +     input wb_rst_i, +     input wb_we_i, +     input wb_stb_i, +     input [15:0] wb_adr_i, +     input [31:0] wb_dat_i,    +     output [31:0] wb_dat_o, +     output reg wb_ack_o, +     output wb_err_o, +     output wb_rty_o, +    +     input stream_clk, +     input stream_rst, +      +     input set_stb, input [7:0] set_addr, input [31:0] set_data, +     output [31:0] status, +     output sys_int_o, +      +     output [31:0] s0, output [31:0] s1, output [31:0] s2, output [31:0] s3, +     output [31:0] s4, output [31:0] s5, output [31:0] s6, output [31:0] s7, +      +     // Write Interfaces +     input [31:0] wr0_data_i, input [3:0] wr0_flags_i, input wr0_ready_i, output wr0_ready_o, +     input [31:0] wr1_data_i, input [3:0] wr1_flags_i, input wr1_ready_i, output wr1_ready_o, +     input [31:0] wr2_data_i, input [3:0] wr2_flags_i, input wr2_ready_i, output wr2_ready_o, +     input [31:0] wr3_data_i, input [3:0] wr3_flags_i, input wr3_ready_i, output wr3_ready_o, +      +     // Read Interfaces +     output [31:0] rd0_data_o, output [3:0] rd0_flags_o, output rd0_ready_o, input rd0_ready_i,  +     output [31:0] rd1_data_o, output [3:0] rd1_flags_o, output rd1_ready_o, input rd1_ready_i,  +     output [31:0] rd2_data_o, output [3:0] rd2_flags_o, output rd2_ready_o, input rd2_ready_i,  +     output [31:0] rd3_data_o, output [3:0] rd3_flags_o, output rd3_ready_o, input rd3_ready_i +     ); +    +   wire [7:0] 	   sel_a; +    +   wire [BUF_SIZE-1:0] 	   buf_addra = wb_adr_i[BUF_SIZE+1:2];     // ignore address 1:0, 32-bit access only +   wire [2:0] 		   which_buf = wb_adr_i[BUF_SIZE+4:BUF_SIZE+2];   // address 15:14 selects the buffer pool +    +   decoder_3_8 dec(.sel(which_buf),.res(sel_a)); +    +   genvar 	 i; +    +   wire 	 go; + +   reg [2:0] 	 port[0:7];	  +   reg [3:0] 	 read_src[0:3]; +   reg [3:0] 	 write_src[0:3]; +    +   wire [7:0] 	 done; +   wire [7:0] 	 error; +   wire [7:0] 	 idle; +    +   wire [31:0] 	 buf_doa[0:7]; +    +   wire [7:0] 	 buf_enb; +   wire [7:0] 	 buf_web; +   wire [BUF_SIZE-1:0] 	 buf_addrb[0:7]; +   wire [31:0] 	 buf_dib[0:7]; +   wire [31:0] 	 buf_dob[0:7]; +    +   wire [31:0] 	 wr_data_i[0:7]; +   wire [3:0] 	 wr_flags_i[0:7]; +   wire [7:0] 	 wr_ready_i; +   wire [7:0] 	 wr_ready_o; +    +   wire [31:0] 	 rd_data_o[0:7]; +   wire [3:0] 	 rd_flags_o[0:7]; +   wire [7:0] 	 rd_ready_o; +   wire [7:0] 	 rd_ready_i; +    +   assign 	 status = {8'd0,idle[7:0],error[7:0],done[7:0]}; + +   assign 	 s0 = buf_addrb[0]; +   assign 	 s1 = buf_addrb[1]; +   assign 	 s2 = buf_addrb[2]; +   assign 	 s3 = buf_addrb[3]; +   assign 	 s4 = buf_addrb[4]; +   assign 	 s5 = buf_addrb[5]; +   assign 	 s6 = buf_addrb[6]; +   assign 	 s7 = buf_addrb[7]; +    +   wire [31:0] 	 fifo_ctrl; +   setting_reg #(.my_addr(SET_ADDR))  +     sreg(.clk(stream_clk),.rst(stream_rst),.strobe(set_stb),.addr(set_addr),.in(set_data), +	  .out(fifo_ctrl),.changed(go)); + +   integer 	 k; +   always @(posedge stream_clk) +     if(stream_rst) +       for(k=0;k<8;k=k+1) +	 port[k] <= 4;   // disabled +     else +       for(k=0;k<8;k=k+1) +	 if(go & (fifo_ctrl[31:28]==k)) +	   port[k] <= fifo_ctrl[27:25]; + +   always @(posedge stream_clk) +     if(stream_rst) +       for(k=0;k<4;k=k+1) +	 read_src[k] <= 8;  // disabled +     else +       for(k=0;k<4;k=k+1) +	 if(go & fifo_ctrl[22] & (fifo_ctrl[27:25]==k)) +	   read_src[k] <= fifo_ctrl[31:28]; +    +   always @(posedge stream_clk) +     if(stream_rst) +       for(k=0;k<4;k=k+1) +	 write_src[k] <= 8;  // disabled +     else +       for(k=0;k<4;k=k+1) +	 if(go & fifo_ctrl[23] & (fifo_ctrl[27:25]==k)) +	   write_src[k] <= fifo_ctrl[31:28]; +    +   generate +      for(i=0;i<8;i=i+1) +	begin : gen_buffer +	   RAMB16_S36_S36 dpram +	     (.DOA(buf_doa[i]),.ADDRA(buf_addra),.CLKA(wb_clk_i),.DIA(wb_dat_i),.DIPA(4'h0), +	      .ENA(wb_stb_i & sel_a[i]),.SSRA(0),.WEA(wb_we_i), +	      .DOB(buf_dob[i]),.ADDRB(buf_addrb[i]),.CLKB(stream_clk),.DIB(buf_dib[i]),.DIPB(4'h0), +	      .ENB(buf_enb[i]),.SSRB(0),.WEB(buf_web[i]) ); +	    +/*	    +	   ram_2port #(.DWIDTH(32),.AWIDTH(BUF_SIZE)) buffer +	     (.clka(wb_clk_i),.ena(wb_stb_i & sel_a[i]),.wea(wb_we_i), +	      .addra(buf_addra),.dia(wb_dat_i),.doa(buf_doa[i]), +	      .clkb(stream_clk),.enb(buf_enb[i]),.web(buf_web[i]), +	      .addrb(buf_addrb[i]),.dib(buf_dib[i]),.dob(buf_dob[i])); +  + */ +	    +	   buffer_int #(.BUF_NUM(i),.BUF_SIZE(BUF_SIZE)) buffer_int +	     (.clk(stream_clk),.rst(stream_rst), +	      .ctrl_word(fifo_ctrl),.go(go & (fifo_ctrl[31:28]==i)), +	      .done(done[i]),.error(error[i]),.idle(idle[i]), +	      .en_o(buf_enb[i]), +	      .we_o(buf_web[i]), +	      .addr_o(buf_addrb[i]), +	      .dat_to_buf(buf_dib[i]), +	      .dat_from_buf(buf_dob[i]), +	      .wr_data_i(wr_data_i[i]), +	      .wr_flags_i(wr_flags_i[i]), +	      .wr_ready_i(wr_ready_i[i]), +	      .wr_ready_o(wr_ready_o[i]), +	      .rd_data_o(rd_data_o[i]), +	      .rd_flags_o(rd_flags_o[i]), +	      .rd_ready_o(rd_ready_o[i]), +	      .rd_ready_i(rd_ready_i[i]) ); +	   mux4 #(.WIDTH(37)) +	     mux4_wr (.en(~port[i][2]),.sel(port[i][1:0]), +		      .i0({wr0_data_i,wr0_flags_i,wr0_ready_i}), +		      .i1({wr1_data_i,wr1_flags_i,wr1_ready_i}), +		      .i2({wr2_data_i,wr2_flags_i,wr2_ready_i}), +		      .i3({wr3_data_i,wr3_flags_i,wr3_ready_i}), +		      .o({wr_data_i[i],wr_flags_i[i],wr_ready_i[i]}) ); +	   mux4 #(.WIDTH(1)) +	     mux4_rd (.en(~port[i][2]),.sel(port[i][1:0]), +		      .i0(rd0_ready_i),.i1(rd1_ready_i),.i2(rd2_ready_i),.i3(rd3_ready_i), +		      .o(rd_ready_i[i])); +	end // block: gen_buffer +   endgenerate + +   //---------------------------------------------------------------------- +   // Wishbone Outputs + +   // Use the following lines if ram output and mux can be made fast enough + +   assign wb_err_o = 1'b0;  // Unused for now +   assign wb_rty_o = 1'b0;  // Unused for now +    +   always @(posedge wb_clk_i) +     wb_ack_o <= wb_stb_i & ~wb_ack_o; +   assign wb_dat_o = buf_doa[which_buf]; + +   // Use this if we can't make the RAM+MUX fast enough +   // reg [31:0] wb_dat_o_reg; +   // reg 	      stb_d1; + +   // always @(posedge wb_clk_i) +   //  begin +   //   wb_dat_o_reg <= buf_doa[which_buf]; +   //   stb_d1 <= wb_stb_i; +   //   wb_ack_o <= (stb_d1 & ~wb_ack_o) | (wb_we_i & wb_stb_i); +   //  end +   //assign     wb_dat_o = wb_dat_o_reg; +    +   mux8 #(.WIDTH(1))  +     mux8_wr0(.en(~write_src[0][3]),.sel(write_src[0][2:0]),  +	      .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), +	      .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]), +	      .o(wr0_ready_o)); + +   mux8 #(.WIDTH(1))  +     mux8_wr1(.en(~write_src[1][3]),.sel(write_src[1][2:0]),  +	      .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), +	      .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]), +	      .o(wr1_ready_o)); + +   mux8 #(.WIDTH(1))  +     mux8_wr2(.en(~write_src[2][3]),.sel(write_src[2][2:0]),  +	      .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), +	      .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]), +	      .o(wr2_ready_o)); + +   mux8 #(.WIDTH(1))  +     mux8_wr3(.en(~write_src[3][3]),.sel(write_src[3][2:0]),  +	      .i0(wr_ready_o[0]), .i1(wr_ready_o[1]), .i2(wr_ready_o[2]), .i3(wr_ready_o[3]), +	      .i4(wr_ready_o[4]), .i5(wr_ready_o[5]), .i6(wr_ready_o[6]), .i7(wr_ready_o[7]), +	      .o(wr3_ready_o)); + +   mux8 #(.WIDTH(37))  +     mux8_rd0(.en(~read_src[0][3]),.sel(read_src[0][2:0]),  +	      .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}), +	      .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}), +	      .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}), +	      .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}), +	      .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}), +	      .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}), +	      .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}), +	      .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}), +	      .o({rd0_data_o,rd0_flags_o,rd0_ready_o})); +    +   mux8 #(.WIDTH(37))  +     mux8_rd1(.en(~read_src[1][3]),.sel(read_src[1][2:0]),  +	      .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}), +	      .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}), +	      .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}), +	      .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}), +	      .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}), +	      .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}), +	      .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}), +	      .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}), +	      .o({rd1_data_o,rd1_flags_o,rd1_ready_o})); +    +   mux8 #(.WIDTH(37))  +     mux8_rd2(.en(~read_src[2][3]),.sel(read_src[2][2:0]),  +	      .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}), +	      .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}), +	      .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}), +	      .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}), +	      .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}), +	      .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}), +	      .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}), +	      .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}), +	      .o({rd2_data_o,rd2_flags_o,rd2_ready_o})); +    +   mux8 #(.WIDTH(37))  +     mux8_rd3(.en(~read_src[3][3]),.sel(read_src[3][2:0]),  +	      .i0({rd_data_o[0],rd_flags_o[0],rd_ready_o[0]}), +	      .i1({rd_data_o[1],rd_flags_o[1],rd_ready_o[1]}), +	      .i2({rd_data_o[2],rd_flags_o[2],rd_ready_o[2]}), +	      .i3({rd_data_o[3],rd_flags_o[3],rd_ready_o[3]}), +	      .i4({rd_data_o[4],rd_flags_o[4],rd_ready_o[4]}), +	      .i5({rd_data_o[5],rd_flags_o[5],rd_ready_o[5]}), +	      .i6({rd_data_o[6],rd_flags_o[6],rd_ready_o[6]}), +	      .i7({rd_data_o[7],rd_flags_o[7],rd_ready_o[7]}), +	      .o({rd3_data_o,rd3_flags_o,rd3_ready_o})); +    +   assign sys_int_o = (|error) | (|done); +    +endmodule // buffer_pool diff --git a/control_lib/newfifo/buffer_pool_tb.v b/control_lib/newfifo/buffer_pool_tb.v new file mode 100644 index 000000000..91a01d268 --- /dev/null +++ b/control_lib/newfifo/buffer_pool_tb.v @@ -0,0 +1,58 @@ + +module buffer_pool_tb(); +    +   wire wb_clk_i; +   wire wb_rst_i; +   wire wb_we_i; +   wire wb_stb_i; +   wire [15:0] wb_adr_i; +   wire [31:0] wb_dat_i;    +   wire [31:0] wb_dat_o; +   wire wb_ack_o; +   wire wb_err_o; +   wire wb_rty_o; + +   wire stream_clk, stream_rst; + +   wire set_stb; +   wire [7:0] set_addr; +   wire [31:0] set_data; + +   wire [31:0] wr0_data, wr1_data, wr2_data, wr3_data; +   wire [31:0] rd0_data, rd1_data, rd2_data, rd3_data; +   wire [3:0]  wr0_flags, wr1_flags, wr2_flags, wr3_flags; +   wire [3:0]  rd0_flags, rd1_flags, rd2_flags, rd3_flags; +   wire        wr0_ready, wr1_ready, wr2_ready, wr3_ready; +   wire        rd0_ready, rd1_ready, rd2_ready, rd3_ready; +   wire        wr0_write, wr1_write, wr2_write, wr3_write; +   wire        rd0_read, rd1_read, rd2_read, rd3_read; + +   buffer_pool dut +     (.wb_clk_i(wb_clk_i), +      .wb_rst_i(wb_rst_i), +      .wb_we_i(wb_we_i), +      .wb_stb_i(wb_stb_i), +      .wb_adr_i(wb_adr_i), +      .wb_dat_i(wb_dat_i),    +      .wb_dat_o(wb_dat_o), +      .wb_ack_o(wb_ack_o), +      .wb_err_o(wb_err_o), +      .wb_rty_o(wb_rty_o), +       +      .stream_clk(stream_clk), +      .stream_rst(stream_rst), +       +      .set_stb(set_stb),.set_addr(set_addr),.set_data(set_data), +       +      .wr0_data_i(wr0_data), .wr0_write_i(wr0_write), .wr0_flags_i(wr0_flags), .wr0_ready_o(wr0_ready), +      .wr1_data_i(wr1_data), .wr1_write_i(wr1_write), .wr1_flags_i(wr1_flags), .wr1_ready_o(wr1_ready), +      .wr2_data_i(wr2_data), .wr2_write_i(wr2_write), .wr2_flags_i(wr2_flags), .wr2_ready_o(wr2_ready), +      .wr3_data_i(wr3_data), .wr3_write_i(wr3_write), .wr3_flags_i(wr3_flags), .wr3_ready_o(wr3_ready), +       +      .rd0_data_o(rd0_data), .rd0_read_i(rd0_read), .rd0_flags_o(rd0_flags), .rd0_ready_o(rd0_ready), +      .rd1_data_o(rd1_data), .rd1_read_i(rd1_read), .rd1_flags_o(rd1_flags), .rd1_ready_o(rd1_ready), +      .rd2_data_o(rd2_data), .rd2_read_i(rd2_read), .rd2_flags_o(rd2_flags), .rd2_ready_o(rd2_ready), +      .rd3_data_o(rd3_data), .rd3_read_i(rd3_read), .rd3_flags_o(rd3_flags), .rd3_ready_o(rd3_ready) +      ); +    +endmodule // buffer_pool_tb | 
