-
Notifications
You must be signed in to change notification settings - Fork 10
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replay FIFO #21
Open
hsangh1596
wants to merge
1
commit into
main
Choose a base branch
from
hsh
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+269
−0
Open
Replay FIFO #21
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<TEST_DATA_CNT; i=i+1) begin | ||
@(posedge clk); | ||
#1 | ||
wren = 1'b0; | ||
if (~full) begin | ||
if (($random()%3)==0) begin // push with 33% probability | ||
wren = 1'b1; | ||
wdata = $urandom(); | ||
data_sb.put(wdata); | ||
$display($time, "ns, pushing %x", wdata); | ||
end | ||
end | ||
end | ||
wren = 1'b0; | ||
end | ||
|
||
// Pop driver/monitor | ||
initial begin | ||
rden = 1'b0; | ||
|
||
@(posedge rst_n); // wait for the reset release | ||
|
||
for (int i=0; i<TEST_DATA_CNT; i=i+1) begin | ||
@(posedge clk); | ||
#1 | ||
rden = 1'b0; | ||
ACK = 1'b0; | ||
NAK = 1'b0; | ||
|
||
if (~empty) begin | ||
// step 1: check | ||
|
||
// peek the expected data from the scoreboard | ||
int peak_result; | ||
logic [DATA_WIDTH-1:0] expected_data; | ||
logic [DATA_WIDTH-1:0] expected_data_test; | ||
peak_result = data_sb.try_peek(expected_data); | ||
|
||
if (peak_result==0) begin | ||
$fatal($time, "ns, the scoreboard is empty: %d", peak_result); | ||
end | ||
|
||
// compare against the rdata | ||
if (expected_data===rdata) begin // "===" instead of "==" to compare against Xs | ||
$display($time, "ns, peeking matching data: %x", rdata); | ||
end | ||
else begin | ||
$fatal($time, "ns, data mismatch: %x (exp) %x (DUT)", expected_data, rdata); | ||
end | ||
|
||
// step 2: pop the entry | ||
if (($random()%3)==0) begin // pop with 33% probability | ||
// pop from the DUT | ||
rden = 1'b1; | ||
// pop from the scoreboard -> 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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<<DEPTH_LG2); | ||
|
||
reg [DATA_WIDTH-1:0] mem[FIFO_DEPTH]; | ||
|
||
reg full, full_n, | ||
empty, empty_n; | ||
reg [DEPTH_LG2:0] wrptr, wrptr_n, // write pointer | ||
rdptr, rdptr_n, // read pointer | ||
rdptr_re; // read pointer buffer to replay | ||
|
||
always_ff @(posedge clk) | ||
if (!rst_n & RST_MEM) begin | ||
for (int i = 0; i < FIFO_DEPTH; i++) begin | ||
mem[i] <= {DATA_WIDTH{1'b0}}; | ||
end | ||
end | ||
else begin | ||
if (wren_i) begin | ||
mem[wrptr[DEPTH_LG2-1:0]] <= wdata_i; // write data | ||
end | ||
end | ||
|
||
always_ff @(posedge clk) | ||
if (!rst_n) begin | ||
full <= 1'b0; | ||
empty <= 1'b1; // empty after as reset | ||
|
||
wrptr <= {(DEPTH_LG2+1){1'b0}}; | ||
rdptr <= {(DEPTH_LG2+1){1'b0}}; | ||
rdptr_re <= {(DEPTH_LG2+1){1'b0}}; | ||
end | ||
else begin | ||
full <= full_n; | ||
empty <= empty_n; | ||
wrptr <= wrptr_n; | ||
|
||
if (NAK) begin | ||
rdptr <= rdptr_re; | ||
end | ||
else begin | ||
rdptr <= rdptr_n; | ||
end | ||
|
||
if (ACK) begin | ||
rdptr_re <= rdptr_n; | ||
end | ||
end | ||
|
||
always_comb begin | ||
wrptr_n = wrptr; | ||
rdptr_n = rdptr; | ||
|
||
if (wren_i) begin | ||
wrptr_n = wrptr + 'd1; | ||
end | ||
|
||
if (rden_i) begin | ||
rdptr_n = rdptr + 'd1; | ||
end | ||
|
||
empty_n = (wrptr_n == rdptr_n); | ||
full_n = (wrptr_n[DEPTH_LG2] != rdptr_n[DEPTH_LG2]) | ||
& (wrptr_n[DEPTH_LG2-1:0] == rdptr_n[DEPTH_LG2-1:0]); | ||
end | ||
|
||
// synthesis translate_off | ||
always @(posedge clk) begin | ||
if (full_o & wren_i) begin | ||
$display("FIFO overflow"); | ||
@(posedge clk); | ||
$finish; | ||
end | ||
end | ||
always @(posedge clk) begin | ||
if (empty_o & rden_i) begin | ||
$display("FIFO underflow"); | ||
@(posedge clk); | ||
$finish; | ||
end | ||
end | ||
// synthesis translate_on | ||
|
||
assign full_o = full; | ||
assign empty_o = empty; | ||
assign rdata_o = mem[rdptr[DEPTH_LG2-1:0]]; | ||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
FIFO_TB.sv | ||
ReplayFIFO.sv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
vcs -full64 -kdb -debug_access+all -LDFLAGS -Wl,--no-as-needed -sverilog -f filelist.f |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Receive an ack sequence number from the input, and update the rdptr_re with the number.