diff --git a/FIFO/Replay_FIFO/FIFO_TB.sv b/FIFO/Replay_FIFO/FIFO_TB.sv new file mode 100644 index 0000000..fc389cb --- /dev/null +++ b/FIFO/Replay_FIFO/FIFO_TB.sv @@ -0,0 +1,158 @@ +// A testbench for a FIFO +`timescale 1ns/10ps + +module FIFO_TB; + + localparam CLK_PERIOD = 10; + localparam FIFO_DEPTH_LG2 = 4; + localparam DATA_WIDTH = 32; + + localparam TEST_DATA_CNT = 128; + localparam TEST_TIMEOUT = 100000; + + + //---------------------------------------------------------- + // Clock and reset generation + //---------------------------------------------------------- + logic clk; + logic rst_n; + + initial begin + clk = 1'b0; + forever + #(CLK_PERIOD/2) clk = ~clk; + end + + initial begin + rst_n = 1'b0; + repeat (3) @(posedge clk); // wait for 3 clocks + rst_n = 1'b1; + end + + //---------------------------------------------------------- + // Design-Under-Test (DUT) + //---------------------------------------------------------- + wire full, empty; + logic wren, rden; + logic [DATA_WIDTH-1:0] wdata, rdata; + logic ACK, NAK; + + FIFO + #( + .DEPTH_LG2 (FIFO_DEPTH_LG2), + .DATA_WIDTH (DATA_WIDTH) + ) + dut + ( + .clk (clk), + .rst_n (rst_n), + + .full_o (full), + .wren_i (wren), + .wdata_i (wdata), + + .empty_o (empty), + .rden_i (rden), + .rdata_o (rdata), + + .ACK (ACK), + .NAK (NAK) + ); + + //---------------------------------------------------------- + // Driver, Monitor, and Scoreboard + //---------------------------------------------------------- + + // A scoreboard to hold expected data + mailbox data_sb = new(); // unlimited size + + // Push driver + initial begin + wren = 1'b0; + wdata = 'hX; + @(posedge rst_n); // wait for the reset release + + for (int i=0; i discard + + #1 + if (($random()%2)==0) begin // ACK with 50% probability + ACK = 1'b1; + NAK = 1'b0; + data_sb.get(expected_data); + $display($time, "ns, popping matching data: %x", rdata); + end else begin // NAK with 50% probability + ACK = 1'b0; + NAK = 1'b1; + $display($time, "ns, NAK occurs and replays: %x", rdata); + end + end + end + end + rden = 1'b0; + + repeat(10) @(posedge clk); + $finish; + end + + // Time-out + initial begin + #TEST_TIMEOUT + $display("Simulation timed out!"); + $fatal("Simulation timed out"); + end + +endmodule diff --git a/FIFO/Replay_FIFO/ReplayFIFO.sv b/FIFO/Replay_FIFO/ReplayFIFO.sv new file mode 100644 index 0000000..a69981a --- /dev/null +++ b/FIFO/Replay_FIFO/ReplayFIFO.sv @@ -0,0 +1,108 @@ +module FIFO #( + parameter DEPTH_LG2 = 4, + parameter DATA_WIDTH = 32, + parameter RST_MEM = 0 +) +( + input wire clk, + input wire rst_n, + + output wire full_o, + input wire wren_i, + input wire [DATA_WIDTH-1:0] wdata_i, + + input wire ACK, // Acknowledge + input wire NAK, // Negative Acknowledge + + output wire empty_o, + input wire rden_i, + output wire [DATA_WIDTH-1:0] rdata_o +); + +localparam FIFO_DEPTH = (1<