diff options
author | Johnathan Corgan <jcorgan@corganenterprises.com> | 2009-08-31 12:08:30 -0700 |
---|---|---|
committer | Johnathan Corgan <jcorgan@corganenterprises.com> | 2009-08-31 12:08:30 -0700 |
commit | 91636cbac2b3edfba45321f1050d0b90b34ab696 (patch) | |
tree | 881275cf214d4cebcc122c60905510f3e6a5226c /control_lib | |
parent | aa37ca0b3b716e23e51f04b6f199ecacf89fe479 (diff) | |
download | uhd-91636cbac2b3edfba45321f1050d0b90b34ab696.tar.gz uhd-91636cbac2b3edfba45321f1050d0b90b34ab696.tar.bz2 uhd-91636cbac2b3edfba45321f1050d0b90b34ab696.zip |
Merged SVN matt/new_eth r10782:11633 into new_eth
* svn diff http://gnuradio.org/svn/branches/developers/matt/new_eth
-r10782:11633
* Patch applied with no conflicts or fuzz.
Diffstat (limited to 'control_lib')
-rw-r--r-- | control_lib/buffer_int.v | 251 | ||||
-rw-r--r-- | control_lib/buffer_pool.v | 323 | ||||
-rw-r--r-- | control_lib/newfifo/cascadefifo_2clock.v | 27 | ||||
-rw-r--r-- | control_lib/newfifo/fifo36_to_ll8.v | 2 | ||||
-rw-r--r-- | control_lib/newfifo/fifo_2clock.v | 66 | ||||
-rw-r--r-- | control_lib/newfifo/fifo_2clock_casc.v | 31 | ||||
-rw-r--r-- | control_lib/newfifo/ll8_shortfifo.v | 13 | ||||
-rw-r--r-- | control_lib/newfifo/newfifo_2clock.v | 82 |
8 files changed, 123 insertions, 672 deletions
diff --git a/control_lib/buffer_int.v b/control_lib/buffer_int.v index c33f2779d..e69de29bb 100644 --- a/control_lib/buffer_int.v +++ b/control_lib/buffer_int.v @@ -1,251 +0,0 @@ - -// 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 BUFF_NUM = 0) - (// Control Interface - input clk, - input rst, - input [31:0] ctrl_word, - input go, - output done, - output error, - output idle, - - // Buffer Interface - output en_o, - output we_o, - output reg [8:0] addr_o, - output [31:0] dat_to_buf, - input [31:0] dat_from_buf, - - // Write FIFO Interface - input [31:0] wr_dat_i, - input wr_write_i, - input wr_done_i, - input wr_error_i, - output reg wr_ready_o, - output reg wr_full_o, - - // Read FIFO Interface - output [31:0] rd_dat_o, - input rd_read_i, - input rd_done_i, - input rd_error_i, - output reg rd_sop_o, - output reg rd_eop_o - ); - - 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] == BUFF_NUM)) - ctrl_reg <= ctrl_word; - - wire [8:0] firstline = ctrl_reg[8:0]; - wire [8:0] lastline = ctrl_reg[17:9]; - wire [3:0] step = ctrl_reg[21:18]; - 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 ? - - assign dat_to_buf = wr_dat_i; - assign rd_dat_o = dat_from_buf; - - 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; - - always @(posedge clk) - if(rst) - begin - state <= IDLE; - rd_sop_o <= 0; - rd_eop_o <= 0; - wr_ready_o <= 0; - wr_full_o <= 0; - end - else - if(clear) - begin - state <= IDLE; - rd_sop_o <= 0; - rd_eop_o <= 0; - wr_ready_o <= 0; - wr_full_o <= 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; - wr_ready_o <= 1; - end - - PRE_READ : - begin - state <= READING; - addr_o <= addr_o + 1; - rd_sop_o <= 1; - end - - READING : - if(rd_error_i) - state <= ERROR; - else if(rd_done_i) - state <= DONE; - else if(rd_read_i) - begin - rd_sop_o <= 0; - addr_o <= addr_o + 1; - if(addr_o == lastline) - rd_eop_o <= 1; - else - rd_eop_o <= 0; - if(rd_eop_o) - state <= DONE; - end - - WRITING : - begin - if(wr_write_i) - addr_o <= addr_o + 1; // This was the timing problem, so now it doesn't depend on wr_error_i - if(wr_error_i) - begin - state <= ERROR; - wr_ready_o <= 0; - end - else - begin - if(wr_write_i) - begin - wr_ready_o <= 0; - if(addr_o == (lastline-1)) - wr_full_o <= 1; - if(addr_o == lastline) - state <= DONE; - end - if(wr_done_i) - begin - state <= DONE; - wr_ready_o <= 0; - end - end // else: !if(wr_error_i) - end // case: WRITING - - DONE : - begin - rd_eop_o <= 0; - rd_sop_o <= 0; - wr_ready_o <= 0; - wr_full_o <= 0; - end - - endcase // case(state) - - // FIXME ignores step for now - - assign we_o = (state == WRITING) && wr_write_i; // FIXME potential critical path - // IF this is a timing problem, we could always write when in this state - assign en_o = ~((state==READING)& ~rd_read_i); // FIXME potential critical path - - assign done = (state == DONE); - assign error = (state == ERROR); - assign idle = (state == IDLE); -endmodule // buffer_int - - - -// These are 2 other ways for doing the WRITING state, both work. First one is faster, but confusing -/* - begin - // Gen 4 values -- state, wr_ready_o, addr_o, wr_full_o - if(~wr_error_i & wr_write_i & (addr_o == (lastline-1))) - wr_full_o <= 1; - if(wr_error_i | wr_write_i | wr_done_i) - wr_ready_o <= 0; - if(wr_error_i) - state <= ERROR; - else if(wr_done_i | (wr_write_i & (addr_o == lastline))) - state <= DONE; - // This one was the timing problem... now we increment addr_o even if there is an error - if(wr_write_i) - addr_o <= addr_o + 1; - end // case: WRITING -*/ - -/* begin - if(wr_error_i) - begin - state <= ERROR; - wr_ready_o <= 0; - end - else - begin - if(wr_write_i) - begin - wr_ready_o <= 0; - addr_o <= addr_o + 1; - if(addr_o == (lastline-1)) - wr_full_o <= 1; - if(addr_o == lastline) - state <= DONE; - end - if(wr_done_i) - begin - state <= DONE; - wr_ready_o <= 0; - end - end // else: !if(wr_error_i) - end // case: WRITING -*/ - - - - - - - - - - - - - - -// Unused old code - //assign rd_empty_o = (state != READING); // && (state != PRE_READ); - //assign rd_empty_o = rd_empty_reg; // timing fix? - //assign rd_ready_o = (state == READING); - //assign rd_ready_o = ~rd_empty_reg; // timing fix? - - //wire rd_en = (state == PRE_READ) || ((state == READING) && rd_read_i); - //wire wr_en = (state == WRITING) && wr_write_i; // IF this is a timing problem, we could always enable when in this state - //assign en_o = rd_en | wr_en; - - // assign wr_full_o = (state != WRITING); - // assign wr_ready_o = (state == WRITING); - diff --git a/control_lib/buffer_pool.v b/control_lib/buffer_pool.v index 969296230..e69de29bb 100644 --- a/control_lib/buffer_pool.v +++ b/control_lib/buffer_pool.v @@ -1,323 +0,0 @@ - -// 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) - -module buffer_pool - (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_dat_i, input wr0_write_i, input wr0_done_i, input wr0_error_i, output wr0_ready_o, output wr0_full_o, - 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, - 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, - 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, - - // Read Interfaces - 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, - 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, - 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, - 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 - ); - - wire [7:0] sel_a; - - wire [2:0] which_buf = wb_adr_i[13:11]; // address 15:14 selects the buffer pool - wire [8:0] buf_addra = wb_adr_i[10:2]; // ignore address 1:0, 32-bit access only - - 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 [8:0] buf_addrb[0:7]; - wire [31:0] buf_dib[0:7]; - wire [31:0] buf_dob[0:7]; - - wire [31:0] wr_dat_i[0:7]; - wire [7:0] wr_write_i; - wire [7:0] wr_done_i; - wire [7:0] wr_error_i; - wire [7:0] wr_ready_o; - wire [7:0] wr_full_o; - - wire [31:0] rd_dat_o[0:7]; - wire [7:0] rd_read_i; - wire [7:0] rd_done_i; - wire [7:0] rd_error_i; - wire [7:0] rd_sop_o; - wire [7:0] rd_eop_o; - - assign status = {8'd0,idle[7:0],error[7:0],done[7:0]}; - - assign s0 = {23'd0,buf_addrb[0]}; - assign s1 = {23'd0,buf_addrb[1]}; - assign s2 = {23'd0,buf_addrb[2]}; - assign s3 = {23'd0,buf_addrb[3]}; - assign s4 = {23'd0,buf_addrb[4]}; - assign s5 = {23'd0,buf_addrb[5]}; - assign s6 = {23'd0,buf_addrb[6]}; - assign s7 = {23'd0,buf_addrb[7]}; - - wire [31:0] fifo_ctrl; - setting_reg #(.my_addr(64)) - 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(9)) 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 #(.BUFF_NUM(i)) fifo_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_dat_i(wr_dat_i[i]), - .wr_write_i(wr_write_i[i]), - .wr_done_i(wr_done_i[i]), - .wr_error_i(wr_error_i[i]), - .wr_ready_o(wr_ready_o[i]), - .wr_full_o(wr_full_o[i]), - .rd_dat_o(rd_dat_o[i]), - .rd_read_i(rd_read_i[i]), - .rd_done_i(rd_done_i[i]), - .rd_error_i(rd_error_i[i]), - .rd_sop_o(rd_sop_o[i]), - .rd_eop_o(rd_eop_o[i]) - ); - - // FIXME -- if it is a problem, maybe we don't need enables on these muxes - mux4 #(.WIDTH(32)) - mux4_dat_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_dat_i),.i1(wr1_dat_i), - .i2(wr2_dat_i),.i3(wr3_dat_i),.o(wr_dat_i[i])); - mux4 #(.WIDTH(1)) - mux4_write_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_write_i),.i1(wr1_write_i), - .i2(wr2_write_i),.i3(wr3_write_i),.o(wr_write_i[i])); - mux4 #(.WIDTH(1)) - mux4_wrdone_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_done_i),.i1(wr1_done_i), - .i2(wr2_done_i),.i3(wr3_done_i),.o(wr_done_i[i])); - mux4 #(.WIDTH(1)) - mux4_wrerror_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(wr0_error_i),.i1(wr1_error_i), - .i2(wr2_error_i),.i3(wr3_error_i),.o(wr_error_i[i])); - mux4 #(.WIDTH(1)) - mux4_read_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_read_i),.i1(rd1_read_i), - .i2(rd2_read_i),.i3(rd3_read_i),.o(rd_read_i[i])); - mux4 #(.WIDTH(1)) - mux4_rddone_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_done_i),.i1(rd1_done_i), - .i2(rd2_done_i),.i3(rd3_done_i),.o(rd_done_i[i])); - mux4 #(.WIDTH(1)) - mux4_rderror_i (.en(~port[i][2]),.sel(port[i][1:0]),.i0(rd0_error_i),.i1(rd1_error_i), - .i2(rd2_error_i),.i3(rd3_error_i),.o(rd_error_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_wr_ready0(.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_wr_full0(.en(~write_src[0][3]),.sel(write_src[0][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr0_full_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_ready1(.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_wr_full1(.en(~write_src[1][3]),.sel(write_src[1][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr1_full_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_ready2(.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_wr_full2(.en(~write_src[2][3]),.sel(write_src[2][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr2_full_o)); - - mux8 #(.WIDTH(1)) - mux8_wr_ready3(.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(1)) - mux8_wr_full3(.en(~write_src[3][3]),.sel(write_src[3][2:0]), .i0(wr_full_o[0]), .i1(wr_full_o[1]), - .i2(wr_full_o[2]), .i3(wr_full_o[3]), .i4(wr_full_o[4]), - .i5(wr_full_o[5]), .i6(wr_full_o[6]), .i7(wr_full_o[7]),.o(wr3_full_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop0(.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd0_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop0(.en(~read_src[0][3]),.sel(read_src[0][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd0_eop_o)); - - mux8 #(.WIDTH(32)) - 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]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd0_dat_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop1(.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd1_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop1(.en(~read_src[1][3]),.sel(read_src[1][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd1_eop_o)); - - mux8 #(.WIDTH(32)) - 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]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd1_dat_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop2(.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd2_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop2(.en(~read_src[2][3]),.sel(read_src[2][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd2_eop_o)); - - mux8 #(.WIDTH(32)) - 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]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd2_dat_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_sop3(.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_sop_o[0]), .i1(rd_sop_o[1]), - .i2(rd_sop_o[2]), .i3(rd_sop_o[3]), .i4(rd_sop_o[4]), - .i5(rd_sop_o[5]), .i6(rd_sop_o[6]), .i7(rd_sop_o[7]),.o(rd3_sop_o)); - - mux8 #(.WIDTH(1)) - mux8_rd_eop3(.en(~read_src[3][3]),.sel(read_src[3][2:0]), .i0(rd_eop_o[0]), .i1(rd_eop_o[1]), - .i2(rd_eop_o[2]), .i3(rd_eop_o[3]), .i4(rd_eop_o[4]), - .i5(rd_eop_o[5]), .i6(rd_eop_o[6]), .i7(rd_eop_o[7]),.o(rd3_eop_o)); - - mux8 #(.WIDTH(32)) - 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]), - .i2(rd_dat_o[2]), .i3(rd_dat_o[3]), .i4(rd_dat_o[4]), - .i5(rd_dat_o[5]), .i6(rd_dat_o[6]), .i7(rd_dat_o[7]),.o(rd3_dat_o)); - - assign sys_int_o = (|error) | (|done); - -endmodule // buffer_pool diff --git a/control_lib/newfifo/cascadefifo_2clock.v b/control_lib/newfifo/cascadefifo_2clock.v new file mode 100644 index 000000000..2abbbf3b5 --- /dev/null +++ b/control_lib/newfifo/cascadefifo_2clock.v @@ -0,0 +1,27 @@ + +module cascadefifo_2clock + #(parameter DWIDTH=32, AWIDTH=9) + (input wclk, input [DWIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output [AWIDTH-1:0] level_wclk, + input rclk, output [DWIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output [AWIDTH-1:0] level_rclk, + input arst); + + wire [DWIDTH-1:0] data_int1, data_int2; + wire src_rdy_int1, src_rdy_int2, dst_rdy_int1, dst_rdy_int2; + + fifo_short #(.WIDTH(DWIDTH)) shortfifo + (.clk(wclk), .reset(arst), .clear(0), + .datain(datain), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), + .dataout(data_int1), .src_rdy_o(src_rdy_int1), .dst_rdy_i(dst_rdy_int1) ); + + newfifo_2clock #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) fifo_2clock + (.wclk(wclk), .datain(data_int1), .src_rdy_i(src_rdy_int1), .dst_rdy_o(dst_rdy_int1), .level_wclk(level_wclk), + .rclk(rclk), .dataout(data_int2), .src_rdy_o(src_rdy_int2), .dst_rdy_i(dst_rdy_int2), .level_rclk(level_rclk), + .arst(arst) ); + + fifo_short #(.WIDTH(DWIDTH)) shortfifo2 + (.clk(rclk), .reset(arst), .clear(0), + .datain(data_int2), .src_rdy_i(src_rdy_int2), .dst_rdy_o(dst_rdy_int2), + .dataout(dataout), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i) ); + +endmodule // fifo_2clock_casc + diff --git a/control_lib/newfifo/fifo36_to_ll8.v b/control_lib/newfifo/fifo36_to_ll8.v index 1befb9e6e..0dee1dfc6 100644 --- a/control_lib/newfifo/fifo36_to_ll8.v +++ b/control_lib/newfifo/fifo36_to_ll8.v @@ -1,6 +1,6 @@ module fifo36_to_ll8 - (input clk, reset, + (input clk, input reset, input clear, input [35:0] f36_data, input f36_src_rdy_i, output f36_dst_rdy_o, diff --git a/control_lib/newfifo/fifo_2clock.v b/control_lib/newfifo/fifo_2clock.v index 6b1eb607e..e69de29bb 100644 --- a/control_lib/newfifo/fifo_2clock.v +++ b/control_lib/newfifo/fifo_2clock.v @@ -1,66 +0,0 @@ - -module fifo_2clock - #(parameter DWIDTH=32, AWIDTH=9) - (input wclk, input [DWIDTH-1:0] datain, input write, output full, output reg [AWIDTH-1:0] level_wclk, - input rclk, output [DWIDTH-1:0] dataout, input read, output empty, output reg [AWIDTH-1:0] level_rclk, - input arst); - - reg [AWIDTH-1:0] wr_addr, rd_addr; - wire [AWIDTH-1:0] wr_addr_rclk, rd_addr_wclk; - wire [AWIDTH-1:0] next_rd_addr; - wire enb_read; - - // Write side management - wire [AWIDTH-1:0] next_wr_addr = wr_addr + 1; - always @(posedge wclk or posedge arst) - if(arst) - wr_addr <= 0; - else if(write) - wr_addr <= next_wr_addr; - assign full = (next_wr_addr == rd_addr_wclk); - - // RAM for data storage. Data out is registered, complicating the - // read side logic - ram_2port #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) mac_rx_ff_ram - (.clka(wclk),.ena(1'b1),.wea(write),.addra(wr_addr),.dia(datain),.doa(), - .clkb(rclk),.enb(enb_read),.web(1'b0),.addrb(next_rd_addr),.dib(0),.dob(dataout) ); - - // Read side management - reg data_valid; - assign empty = ~data_valid; - assign next_rd_addr = rd_addr + data_valid; - assign enb_read = read | ~data_valid; - - always @(posedge rclk or posedge arst) - if(arst) - rd_addr <= 0; - else if(read) - rd_addr <= rd_addr + 1; - - always @(posedge rclk or posedge arst) - if(arst) - data_valid <= 0; - else - if(read & (next_rd_addr == wr_addr_rclk)) - data_valid <= 0; - else if(next_rd_addr != wr_addr_rclk) - data_valid <= 1; - - // Send pointers across clock domains via gray code - gray_send #(.WIDTH(AWIDTH)) send_wr_addr - (.clk_in(wclk),.addr_in(wr_addr), - .clk_out(rclk),.addr_out(wr_addr_rclk) ); - - gray_send #(.WIDTH(AWIDTH)) send_rd_addr - (.clk_in(rclk),.addr_in(rd_addr), - .clk_out(wclk),.addr_out(rd_addr_wclk) ); - - // Generate fullness info, these are approximate and may be delayed - // and are only for higher-level flow control. - // Only full and empty are guaranteed exact. - always @(posedge wclk) - level_wclk <= wr_addr - rd_addr_wclk; - always @(posedge rclk) - level_rclk <= wr_addr_rclk - rd_addr; - -endmodule // fifo_2clock diff --git a/control_lib/newfifo/fifo_2clock_casc.v b/control_lib/newfifo/fifo_2clock_casc.v index e9b0cfc25..e69de29bb 100644 --- a/control_lib/newfifo/fifo_2clock_casc.v +++ b/control_lib/newfifo/fifo_2clock_casc.v @@ -1,31 +0,0 @@ - -module fifo_2clock_casc - #(parameter DWIDTH=32, AWIDTH=9) - (input wclk, input [DWIDTH-1:0] datain, input write, output full, output [AWIDTH-1:0] level_wclk, - input rclk, output [DWIDTH-1:0] dataout, input read, output empty, output [AWIDTH-1:0] level_rclk, - input arst); - - wire full_int, empty_int, full_int2, empty_int2, transfer, transfer2; - wire [DWIDTH-1:0] data_int, data_int2; - - shortfifo #(.WIDTH(DWIDTH)) shortfifo - (.clk(wclk), .rst(arst), .clear(0), - .datain(datain), .write(write), .full(full), - .dataout(data_int), .read(transfer), .empty(empty_int) ); - - assign transfer = ~full_int & ~empty_int; - - fifo_2clock #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) fifo_2clock - (.wclk(wclk), .datain(data_int), .write(transfer), .full(full_int), .level_wclk(level_wclk), - .rclk(rclk), .dataout(data_int2), .read(transfer2), .empty(empty_int2), .level_rclk(level_rclk), - .arst(arst) ); - - assign transfer2 = ~full_int2 & ~empty_int2; - - shortfifo #(.WIDTH(DWIDTH)) shortfifo2 - (.clk(rclk), .rst(arst), .clear(0), - .datain(data_int2), .write(transfer2), .full(full_int2), - .dataout(dataout), .read(read), .empty(empty) ); - -endmodule // fifo_2clock_casc - diff --git a/control_lib/newfifo/ll8_shortfifo.v b/control_lib/newfifo/ll8_shortfifo.v new file mode 100644 index 000000000..39ada9a4f --- /dev/null +++ b/control_lib/newfifo/ll8_shortfifo.v @@ -0,0 +1,13 @@ + + +module ll8_shortfifo + (input clk, input reset, input clear, + input [7:0] datain, input sof_i, input eof_i, input error_i, input src_rdy_i, output dst_rdy_o, + output [7:0] dataout, output sof_o, output eof_o, output error_o, output src_rdy_o, input dst_rdy_i); + + fifo_short #(.WIDTH(11)) fifo_short + (.clk(clk), .reset(reset), .clear(clear), + .datain({error_i,eof_i,sof_i,datain}), .src_rdy_i(src_rdy_i), .dst_rdy_o(dst_rdy_o), + .dataout({error_o,eof_o,sof_o,dataout}), .src_rdy_o(src_rdy_o), .dst_rdy_i(dst_rdy_i)); + +endmodule // ll8_shortfifo diff --git a/control_lib/newfifo/newfifo_2clock.v b/control_lib/newfifo/newfifo_2clock.v new file mode 100644 index 000000000..23a6f693c --- /dev/null +++ b/control_lib/newfifo/newfifo_2clock.v @@ -0,0 +1,82 @@ + +module newfifo_2clock + #(parameter DWIDTH=32, AWIDTH=9) + (input wclk, input [DWIDTH-1:0] datain, input src_rdy_i, output dst_rdy_o, output reg [AWIDTH-1:0] level_wclk, + input rclk, output [DWIDTH-1:0] dataout, output src_rdy_o, input dst_rdy_i, output reg [AWIDTH-1:0] level_rclk, + input arst); + + wire full, empty, write, read; + + assign dst_rdy_o = ~full; + assign src_rdy_o = ~empty; + assign write = src_rdy_i & dst_rdy_o; + assign read = src_rdy_o & dst_rdy_i; + +//`define USE_XLNX_FIFO 1 +`ifdef USE_XLNX_FIFO + fifo_xlnx_512x36_2clk mac_tx_fifo_2clk + (.rst(rst), + .wr_clk(wclk),.din(datain),.full(full),.wr_en(write),.wr_data_count(fifo_occupied[8:0]), + .rd_clk(rclk),.dout(dataout),.empty(empty),.rd_en(read),.rd_data_count() ); +`else + // ISE sucks, so the following doesn't work properly + + reg [AWIDTH-1:0] wr_addr, rd_addr; + wire [AWIDTH-1:0] wr_addr_rclk, rd_addr_wclk; + wire [AWIDTH-1:0] next_rd_addr; + wire enb_read; + + // Write side management + wire [AWIDTH-1:0] next_wr_addr = wr_addr + 1; + always @(posedge wclk or posedge arst) + if(arst) + wr_addr <= 0; + else if(write) + wr_addr <= next_wr_addr; + assign full = (next_wr_addr == rd_addr_wclk); + + // RAM for data storage. Data out is registered, complicating the + // read side logic + ram_2port #(.DWIDTH(DWIDTH),.AWIDTH(AWIDTH)) mac_rx_ff_ram + (.clka(wclk),.ena(1'b1),.wea(write),.addra(wr_addr),.dia(datain),.doa(), + .clkb(rclk),.enb(enb_read),.web(1'b0),.addrb(next_rd_addr),.dib(0),.dob(dataout) ); + + // Read side management + reg data_valid; + assign empty = ~data_valid; + assign next_rd_addr = rd_addr + data_valid; + assign enb_read = read | ~data_valid; + + always @(posedge rclk or posedge arst) + if(arst) + rd_addr <= 0; + else if(read) + rd_addr <= rd_addr + 1; + + always @(posedge rclk or posedge arst) + if(arst) + data_valid <= 0; + else + if(read & (next_rd_addr == wr_addr_rclk)) + data_valid <= 0; + else if(next_rd_addr != wr_addr_rclk) + data_valid <= 1; + + // Send pointers across clock domains via gray code + gray_send #(.WIDTH(AWIDTH)) send_wr_addr + (.clk_in(wclk),.addr_in(wr_addr), + .clk_out(rclk),.addr_out(wr_addr_rclk) ); + + gray_send #(.WIDTH(AWIDTH)) send_rd_addr + (.clk_in(rclk),.addr_in(rd_addr), + .clk_out(wclk),.addr_out(rd_addr_wclk) ); + + // Generate fullness info, these are approximate and may be delayed + // and are only for higher-level flow control. + // Only full and empty are guaranteed exact. + always @(posedge wclk) + level_wclk <= wr_addr - rd_addr_wclk; + always @(posedge rclk) + level_rclk <= wr_addr_rclk - rd_addr; +`endif +endmodule // fifo_2clock |