aboutsummaryrefslogtreecommitdiffstats
path: root/control_lib
diff options
context:
space:
mode:
authorJohnathan Corgan <jcorgan@corganenterprises.com>2009-08-31 12:08:30 -0700
committerJohnathan Corgan <jcorgan@corganenterprises.com>2009-08-31 12:08:30 -0700
commit91636cbac2b3edfba45321f1050d0b90b34ab696 (patch)
tree881275cf214d4cebcc122c60905510f3e6a5226c /control_lib
parentaa37ca0b3b716e23e51f04b6f199ecacf89fe479 (diff)
downloaduhd-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.v251
-rw-r--r--control_lib/buffer_pool.v323
-rw-r--r--control_lib/newfifo/cascadefifo_2clock.v27
-rw-r--r--control_lib/newfifo/fifo36_to_ll8.v2
-rw-r--r--control_lib/newfifo/fifo_2clock.v66
-rw-r--r--control_lib/newfifo/fifo_2clock_casc.v31
-rw-r--r--control_lib/newfifo/ll8_shortfifo.v13
-rw-r--r--control_lib/newfifo/newfifo_2clock.v82
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