From fb04ad0eb86ea0cfa65be66c09c8424213c9c932 Mon Sep 17 00:00:00 2001 From: Matt Ettus Date: Wed, 2 Sep 2009 17:28:57 -0700 Subject: cleaning up the new fifos --- control_lib/newfifo/cascadefifo_2clock.v | 27 ------ control_lib/newfifo/fifo_2clock.v | 82 ++++++++++++++++ control_lib/newfifo/fifo_2clock_cascade.v | 27 ++++++ control_lib/newfifo/fifo_tb.v | 155 ------------------------------ control_lib/newfifo/newfifo_2clock.v | 82 ---------------- 5 files changed, 109 insertions(+), 264 deletions(-) delete mode 100644 control_lib/newfifo/cascadefifo_2clock.v create mode 100644 control_lib/newfifo/fifo_2clock.v create mode 100644 control_lib/newfifo/fifo_2clock_cascade.v delete mode 100644 control_lib/newfifo/fifo_tb.v delete mode 100644 control_lib/newfifo/newfifo_2clock.v (limited to 'control_lib') diff --git a/control_lib/newfifo/cascadefifo_2clock.v b/control_lib/newfifo/cascadefifo_2clock.v deleted file mode 100644 index 2abbbf3b5..000000000 --- a/control_lib/newfifo/cascadefifo_2clock.v +++ /dev/null @@ -1,27 +0,0 @@ - -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/fifo_2clock.v b/control_lib/newfifo/fifo_2clock.v new file mode 100644 index 000000000..23a6f693c --- /dev/null +++ b/control_lib/newfifo/fifo_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 diff --git a/control_lib/newfifo/fifo_2clock_cascade.v b/control_lib/newfifo/fifo_2clock_cascade.v new file mode 100644 index 000000000..2abbbf3b5 --- /dev/null +++ b/control_lib/newfifo/fifo_2clock_cascade.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/fifo_tb.v b/control_lib/newfifo/fifo_tb.v deleted file mode 100644 index 98fd63f8d..000000000 --- a/control_lib/newfifo/fifo_tb.v +++ /dev/null @@ -1,155 +0,0 @@ -module fifo_tb(); - - reg clk, rst; - wire short_full, short_empty, long_full, long_empty; - wire casc_full, casc_empty, casc2_full, casc2_empty; - reg read, write; - - wire [7:0] short_do, long_do; - wire [7:0] casc_do, casc2_do; - reg [7:0] di; - - reg clear = 0; - - shortfifo #(.WIDTH(8)) shortfifo - (.clk(clk),.rst(rst),.datain(di),.dataout(short_do),.clear(clear), - .read(read),.write(write),.full(short_full),.empty(short_empty)); - - longfifo #(.WIDTH(8), .SIZE(4)) longfifo - (.clk(clk),.rst(rst),.datain(di),.dataout(long_do),.clear(clear), - .read(read),.write(write),.full(long_full),.empty(long_empty)); - - cascadefifo #(.WIDTH(8), .SIZE(4)) cascadefifo - (.clk(clk),.rst(rst),.datain(di),.dataout(casc_do),.clear(clear), - .read(read),.write(write),.full(casc_full),.empty(casc_empty)); - - cascadefifo2 #(.WIDTH(8), .SIZE(4)) cascadefifo2 - (.clk(clk),.rst(rst),.datain(di),.dataout(casc2_do),.clear(clear), - .read(read),.write(write),.full(casc2_full),.empty(casc2_empty)); - - initial rst = 1; - initial #1000 rst = 0; - initial clk = 0; - always #50 clk = ~clk; - - initial di = 8'hAE; - initial read = 0; - initial write = 0; - - always @(posedge clk) - if(write) - di <= di + 1; - - always @(posedge clk) - begin - if(short_full != long_full) - $display("Error: FULL mismatch"); - if(short_empty != long_empty) - $display("Note: EMPTY mismatch, usually not a problem (longfifo has 2 cycle latency)"); - if(read & (short_do != long_do)) - $display("Error: DATA mismatch"); - end - - initial $dumpfile("fifo_tb.vcd"); - initial $dumpvars(0,fifo_tb); - - initial - begin - @(negedge rst); - @(posedge clk); - repeat (10) - @(posedge clk); - write <= 1; - @(posedge clk); - write <= 0; - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - read <= 1; - @(posedge clk); - read <= 0; - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - - repeat(10) - begin - write <= 1; - @(posedge clk); - write <= 0; - @(posedge clk); - @(posedge clk); - @(posedge clk); - read <= 1; - @(posedge clk); - read <= 0; - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - end // repeat (10) - - write <= 1; - repeat (4) - @(posedge clk); - write <= 0; - @(posedge clk); - read <= 1; - repeat (4) - @(posedge clk); - read <= 0; - @(posedge clk); - - - write <= 1; - repeat (4) - @(posedge clk); - write <= 0; - @(posedge clk); - repeat (4) - begin - read <= 1; - @(posedge clk); - read <= 0; - @(posedge clk); - end - - write <= 1; - @(posedge clk); - @(posedge clk); - @(posedge clk); - @(posedge clk); - read <= 1; - repeat (5) - @(posedge clk); - write <= 0; - @(posedge clk); - @(posedge clk); - read <= 0; - @(posedge clk); - - write <= 1; - repeat (16) - @(posedge clk); - write <= 0; - @(posedge clk); - - read <= 1; - repeat (16) - @(posedge clk); - read <= 0; - @(posedge clk); - - repeat (10) - @(posedge clk); - $finish; - end -endmodule // longfifo_tb diff --git a/control_lib/newfifo/newfifo_2clock.v b/control_lib/newfifo/newfifo_2clock.v deleted file mode 100644 index 23a6f693c..000000000 --- a/control_lib/newfifo/newfifo_2clock.v +++ /dev/null @@ -1,82 +0,0 @@ - -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 -- cgit v1.2.3