diff --git a/fw/project/lcmxo2/sc64.ldf b/fw/project/lcmxo2/sc64.ldf
index 20dcae1..5d2cc62 100644
--- a/fw/project/lcmxo2/sc64.ldf
+++ b/fw/project/lcmxo2/sc64.ldf
@@ -15,6 +15,9 @@
+
+
+
diff --git a/fw/project/lcmxo2/sc64.lpf b/fw/project/lcmxo2/sc64.lpf
index 2d61e26..3fd38a2 100644
--- a/fw/project/lcmxo2/sc64.lpf
+++ b/fw/project/lcmxo2/sc64.lpf
@@ -214,7 +214,7 @@ LOCATE COMP "usb_miso" SITE "10" ;
LOCATE COMP "usb_pwrsav" SITE "2" ;
SYSCONFIG SDM_PORT=DISABLE I2C_PORT=ENABLE ;
VOLTAGE 3.300 V;
-FREQUENCY NET "clk" 100.000000 MHz PAR_ADJ 20.000000 ;
+FREQUENCY NET "clk" 100.000000 MHz ;
BLOCK PATH TO PORT "mcu_int" ;
BLOCK PATH TO PORT "n64_irq" ;
BLOCK PATH FROM PORT "usb_pwrsav" ;
diff --git a/fw/rtl/fifo/fifo_bus.sv b/fw/rtl/fifo/fifo_bus.sv
index 80ca607..9d3c17f 100644
--- a/fw/rtl/fifo/fifo_bus.sv
+++ b/fw/rtl/fifo/fifo_bus.sv
@@ -1,35 +1,29 @@
interface fifo_bus ();
logic rx_empty;
- logic rx_almost_empty;
logic rx_read;
logic [7:0] rx_rdata;
logic tx_full;
- logic tx_almost_full;
logic tx_write;
logic [7:0] tx_wdata;
modport controller (
input rx_empty,
- input rx_almost_empty,
output rx_read,
input rx_rdata,
input tx_full,
- input tx_almost_full,
output tx_write,
output tx_wdata
);
modport fifo (
output rx_empty,
- output rx_almost_empty,
input rx_read,
output rx_rdata,
output tx_full,
- output tx_almost_full,
input tx_write,
input tx_wdata
);
diff --git a/fw/rtl/fifo/fifo_junction.sv b/fw/rtl/fifo/fifo_junction.sv
index cd3ffdc..459c218 100644
--- a/fw/rtl/fifo/fifo_junction.sv
+++ b/fw/rtl/fifo/fifo_junction.sv
@@ -11,16 +11,12 @@ module fifo_junction (
dev_bus.tx_wdata = cfg_bus.tx_write ? cfg_bus.tx_wdata : dma_bus.tx_wdata;
cfg_bus.rx_empty = dev_bus.rx_empty;
- cfg_bus.rx_almost_empty = dev_bus.rx_almost_empty;
cfg_bus.rx_rdata = dev_bus.rx_rdata;
cfg_bus.tx_full = dev_bus.tx_full;
- cfg_bus.tx_almost_full = dev_bus.tx_almost_full;
dma_bus.rx_empty = dev_bus.rx_empty;
- dma_bus.rx_almost_empty = dev_bus.rx_almost_empty;
dma_bus.rx_rdata = dev_bus.rx_rdata;
dma_bus.tx_full = dev_bus.tx_full;
- dma_bus.tx_almost_full = dev_bus.tx_almost_full;
end
endmodule
diff --git a/fw/rtl/memory/memory_sdram.sv b/fw/rtl/memory/memory_sdram.sv
index f112241..0d4179b 100644
--- a/fw/rtl/memory/memory_sdram.sv
+++ b/fw/rtl/memory/memory_sdram.sv
@@ -22,20 +22,22 @@ module memory_sdram (
// in nanoseconds
localparam real T_INIT = 100_000.0;
- localparam real T_RC = 60.0;
- localparam real T_RP = 15.0;
- localparam real T_RCD = 15.0;
localparam real T_MRD = 14.0;
+ localparam real T_RAS = 37.0;
+ localparam real T_RC = 60.0;
+ localparam real T_RCD = 15.0;
localparam real T_REF = 7_812.5;
+ localparam real T_RP = 15.0;
localparam real T_CLK = (1.0 / FREQUENCY) * 1_000_000_000.0;
const bit [13:0] C_INIT = 14'(int'($ceil(T_INIT / T_CLK)));
- const bit [4:0] C_RC = 5'(int'($ceil(T_RC / T_CLK)));
- const bit [4:0] C_RP = 5'(int'($ceil(T_RP / T_CLK)));
- const bit [4:0] C_RCD = 5'(int'($ceil(T_RCD / T_CLK)));
const bit [4:0] C_MRD = 5'(int'($ceil(T_MRD / T_CLK)));
+ const bit [2:0] C_RAS = 3'(int'($ceil(T_RAS / T_CLK)));
+ const bit [4:0] C_RC = 5'(int'($ceil(T_RC / T_CLK)));
+ const bit [4:0] C_RCD = 5'(int'($ceil(T_RCD / T_CLK)));
const bit [13:0] C_REF = 14'(int'($ceil(T_REF / T_CLK)));
+ const bit [4:0] C_RP = 5'(int'($ceil(T_RP / T_CLK)));
const bit [4:0] INIT_PRECHARGE = 5'd0;
const bit [4:0] INIT_REFRESH_1 = INIT_PRECHARGE + C_RP;
@@ -139,8 +141,10 @@ module memory_sdram (
logic [13:0] refresh_counter;
logic [4:0] wait_counter;
+ logic [2:0] precharge_counter;
logic powerup_done;
logic pending_refresh;
+ logic precharge_valid;
always_ff @(posedge clk) begin
refresh_counter <= refresh_counter + 1'd1;
@@ -170,6 +174,17 @@ module memory_sdram (
if (state != next_state) begin
wait_counter <= 5'd0;
end
+
+ precharge_counter <= precharge_counter + 1'd1;
+
+ if (precharge_counter >= C_RAS - 2'd2) begin
+ precharge_valid <= 1'b1;
+ end
+
+ if (sdram_next_cmd == CMD_ACT) begin
+ precharge_counter <= 3'd0;
+ precharge_valid <= 1'b0;
+ end
end
logic [(CAS_LATENCY):0] read_cmd_ack_delay;
@@ -228,14 +243,14 @@ module memory_sdram (
end
S_ACTIVE: begin
- if (pending_refresh) begin
+ if (pending_refresh && precharge_valid) begin
next_state = S_PRECHARGE;
sdram_next_cmd = CMD_PRE;
end else if (mem_bus.request) begin
if (request_in_current_active_bank_row) begin
next_state = S_BUSY;
sdram_next_cmd = mem_bus.write ? CMD_WRITE : CMD_READ;
- end else begin
+ end else if (precharge_valid) begin
next_state = S_PRECHARGE;
sdram_next_cmd = CMD_PRE;
end
diff --git a/fw/rtl/sd/sd_dat.sv b/fw/rtl/sd/sd_dat.sv
index 419efa8..00c88c4 100644
--- a/fw/rtl/sd/sd_dat.sv
+++ b/fw/rtl/sd/sd_dat.sv
@@ -36,12 +36,10 @@ module sd_dat (
// FIFO
logic rx_full;
- logic rx_almost_full;
logic rx_write;
logic [7:0] rx_wdata;
logic tx_empty;
- logic tx_almost_empty;
logic tx_read;
logic [7:0] tx_rdata;
@@ -50,12 +48,10 @@ module sd_dat (
.reset(reset || sd_scb.dat_fifo_flush),
.empty(fifo_bus.rx_empty),
- .almost_empty(fifo_bus.rx_almost_empty),
.read(fifo_bus.rx_read),
.rdata(fifo_bus.rx_rdata),
.full(rx_full),
- .almost_full(rx_almost_full),
.write(rx_write),
.wdata(rx_wdata),
@@ -67,12 +63,10 @@ module sd_dat (
.reset(reset || sd_scb.dat_fifo_flush),
.empty(tx_empty),
- .almost_empty(tx_almost_empty),
.read(tx_read),
.rdata(tx_rdata),
.full(fifo_bus.tx_full),
- .almost_full(fifo_bus.tx_almost_full),
.write(fifo_bus.tx_write),
.wdata(fifo_bus.tx_wdata),
diff --git a/fw/rtl/usb/usb_ft1248.sv b/fw/rtl/usb/usb_ft1248.sv
index d60d8ad..0a31308 100644
--- a/fw/rtl/usb/usb_ft1248.sv
+++ b/fw/rtl/usb/usb_ft1248.sv
@@ -1,42 +1,3 @@
-interface usb_scb ();
-
- logic fifo_flush;
- logic fifo_flush_busy;
- logic write_buffer_flush;
- logic [10:0] rx_count;
- logic [10:0] tx_count;
- logic pwrsav;
- logic reset_state;
- logic reset_on_ack;
- logic reset_off_ack;
-
- modport controller (
- output fifo_flush,
- input fifo_flush_busy,
- output write_buffer_flush,
- input rx_count,
- input tx_count,
- input pwrsav,
- input reset_state,
- output reset_on_ack,
- output reset_off_ack
- );
-
- modport usb (
- input fifo_flush,
- output fifo_flush_busy,
- input write_buffer_flush,
- output rx_count,
- output tx_count,
- output pwrsav,
- output reset_state,
- input reset_on_ack,
- input reset_off_ack
- );
-
-endinterface
-
-
module usb_ft1248 (
input clk,
input reset,
@@ -53,12 +14,10 @@ module usb_ft1248 (
);
logic rx_full;
- logic rx_almost_full;
- logic rx_write;
+ logic rx_write_delayed;
logic [7:0] rx_wdata;
logic tx_empty;
- logic tx_almost_empty;
logic tx_read;
logic [7:0] tx_rdata;
@@ -69,13 +28,11 @@ module usb_ft1248 (
.reset(reset || fifo_flush),
.empty(fifo_bus.rx_empty),
- .almost_empty(fifo_bus.rx_almost_empty),
.read(fifo_bus.rx_read),
.rdata(fifo_bus.rx_rdata),
.full(rx_full),
- .almost_full(rx_almost_full),
- .write(rx_write),
+ .write(rx_write_delayed),
.wdata(rx_wdata),
.count(usb_scb.rx_count)
@@ -86,12 +43,10 @@ module usb_ft1248 (
.reset(reset || fifo_flush),
.empty(tx_empty),
- .almost_empty(tx_almost_empty),
.read(tx_read),
.rdata(tx_rdata),
.full(fifo_bus.tx_full),
- .almost_full(fifo_bus.tx_almost_full),
.write(fifo_bus.tx_write),
.wdata(fifo_bus.tx_wdata),
@@ -145,6 +100,8 @@ module usb_ft1248 (
e_cmd cmd;
e_cmd next_cmd;
logic [3:0] phase;
+ logic rx_write;
+ logic last_rx_failed;
logic last_tx_failed;
logic reset_reply;
logic [4:0] modem_status_counter;
@@ -158,6 +115,8 @@ module usb_ft1248 (
usb_scb.pwrsav <= !ft_pwrsav;
fifo_flush <= 1'b0;
+ rx_write_delayed <= rx_write;
+
phase <= {phase[2:0], phase[3]};
if (state == STATE_IDLE) begin
phase <= 4'b0100;
@@ -166,6 +125,7 @@ module usb_ft1248 (
if (reset) begin
usb_scb.fifo_flush_busy <= 1'b0;
usb_scb.reset_state <= 1'b0;
+ last_rx_failed <= 1'b0;
last_tx_failed <= 1'b0;
reset_reply <= 1'b0;
modem_status_counter <= 5'd0;
@@ -195,9 +155,19 @@ module usb_ft1248 (
if (usb_scb.fifo_flush_busy) begin
usb_scb.fifo_flush_busy <= 1'b0;
fifo_flush <= 1'b1;
+ last_rx_failed <= 1'b0;
+ last_tx_failed <= 1'b0;
+ end else if (last_rx_failed && !rx_full) begin
+ last_rx_failed <= 1'b0;
+ rx_write_delayed <= 1'b1;
end
end
+ if ((state == STATE_DATA) && (cmd == CMD_READ) && phase[3]) begin
+ rx_wdata <= ft_miosi_in;
+ last_rx_failed <= !ft_miso && rx_full;
+ end
+
if ((state == STATE_DATA) && (cmd == CMD_WRITE) && phase[3]) begin
last_tx_failed <= ft_miso;
end
@@ -262,8 +232,6 @@ module usb_ft1248 (
rx_write = 1'b0;
tx_read = 1'b0;
- rx_wdata = ft_miosi_in;
-
if (!ft_miso && phase[3]) begin
case (state)
STATE_STATUS: begin
@@ -273,13 +241,15 @@ module usb_ft1248 (
end
STATE_DATA: begin
- if (cmd == CMD_READ) begin
+ if (cmd == CMD_READ && !rx_full) begin
rx_write = 1'b1;
end
if (cmd == CMD_WRITE && !tx_empty) begin
tx_read = 1'b1;
end
end
+
+ default: begin end
endcase
end
end
@@ -340,7 +310,7 @@ module usb_ft1248 (
if (ft_miso) begin
next_state = STATE_DESELECT;
end else if (cmd == CMD_READ) begin
- if (rx_almost_full) begin
+ if (rx_full) begin
next_state = STATE_DESELECT;
end
end else if (cmd == CMD_WRITE) begin
diff --git a/fw/rtl/usb/usb_scb.sv b/fw/rtl/usb/usb_scb.sv
new file mode 100644
index 0000000..b2a322d
--- /dev/null
+++ b/fw/rtl/usb/usb_scb.sv
@@ -0,0 +1,37 @@
+interface usb_scb ();
+
+ logic fifo_flush;
+ logic fifo_flush_busy;
+ logic write_buffer_flush;
+ logic [10:0] rx_count;
+ logic [10:0] tx_count;
+ logic pwrsav;
+ logic reset_state;
+ logic reset_on_ack;
+ logic reset_off_ack;
+
+ modport controller (
+ output fifo_flush,
+ input fifo_flush_busy,
+ output write_buffer_flush,
+ input rx_count,
+ input tx_count,
+ input pwrsav,
+ input reset_state,
+ output reset_on_ack,
+ output reset_off_ack
+ );
+
+ modport usb (
+ input fifo_flush,
+ output fifo_flush_busy,
+ input write_buffer_flush,
+ output rx_count,
+ output tx_count,
+ output pwrsav,
+ output reset_state,
+ input reset_on_ack,
+ input reset_off_ack
+ );
+
+endinterface
diff --git a/fw/rtl/vendor/lcmxo2/fifo_8kb.sv b/fw/rtl/vendor/lcmxo2/fifo_8kb.sv
index db02ad2..05fb8b3 100644
--- a/fw/rtl/vendor/lcmxo2/fifo_8kb.sv
+++ b/fw/rtl/vendor/lcmxo2/fifo_8kb.sv
@@ -3,18 +3,19 @@ module fifo_8kb (
input reset,
output empty,
- output almost_empty,
input read,
output [7:0] rdata,
output full,
- output almost_full,
input write,
input [7:0] wdata,
-
+
output logic [10:0] count
);
+ logic almost_empty;
+ logic almost_full;
+
fifo_8kb_lattice_generated fifo_8kb_lattice_generated_inst (
.Data(wdata),
.WrClock(clk),
@@ -25,7 +26,7 @@ module fifo_8kb (
.RPReset(reset),
.Q(rdata),
.Empty(empty),
- .Full(full),
+ .Full(full),
.AlmostEmpty(almost_empty),
.AlmostFull(almost_full)
);
diff --git a/fw/tests/Makefile b/fw/tests/Makefile
index 0c17476..42e11a1 100644
--- a/fw/tests/Makefile
+++ b/fw/tests/Makefile
@@ -1,4 +1,5 @@
RTL_DIR = ../rtl
+BENCHES_DIR = benches
MOCKS_DIR = mocks
BUILD_DIR = build
SRC_DIRS = \
@@ -11,10 +12,11 @@ SRC_DIRS = \
$(RTL_DIR)/usb \
$(RTL_DIR)/vendor \
$(RTL_DIR) \
+ $(MOCKS_DIR)/vendor \
$(MOCKS_DIR)
INC_DIRS = $(addprefix -I, $(SRC_DIRS))
-TEST_FILES = $(shell find "./" -not -path "$(BUILD_DIR)/*" -type f -name "*_tb.sv")
+TEST_FILES = $(shell find "./$(BENCHES_DIR)" -not -path "$(BUILD_DIR)/*" -type f -name "*_tb.sv")
TESTS = $(addprefix $(BUILD_DIR)/, $(basename $(TEST_FILES)))
VERILATOR_FLAGS = --binary --trace --timescale 10ns/1ns -j --quiet $(INC_DIRS)
diff --git a/fw/tests/memory/memory_dma_tb.sv b/fw/tests/benches/memory_dma_tb.sv
similarity index 96%
rename from fw/tests/memory/memory_dma_tb.sv
rename to fw/tests/benches/memory_dma_tb.sv
index 359c54b..aa08d5a 100644
--- a/fw/tests/memory/memory_dma_tb.sv
+++ b/fw/tests/benches/memory_dma_tb.sv
@@ -41,11 +41,11 @@ module memory_dma_tb;
.transfer_length(transfer_length)
);
- fifo_bus_mock #(
+ fifo_bus_fifo_mock #(
.DEPTH(16),
.FILL_RATE(16),
.DRAIN_RATE(16)
- ) fifo_bus_mock (
+ ) fifo_bus_fifo_mock (
.clk(clk),
.reset(reset),
@@ -103,7 +103,7 @@ module memory_dma_tb;
#1;
stop = 1'b0;
- #99;
+ #165;
start = 1'b1;
direction = 1'b1;
diff --git a/fw/tests/benches/usb_ft1248_tb.sv b/fw/tests/benches/usb_ft1248_tb.sv
new file mode 100644
index 0000000..8c62dd5
--- /dev/null
+++ b/fw/tests/benches/usb_ft1248_tb.sv
@@ -0,0 +1,119 @@
+module usb_ft1248_tb;
+
+ logic clk;
+ logic reset;
+
+ usb_scb usb_scb ();
+ fifo_bus fifo_bus ();
+
+ logic usb_pwrsav;
+ logic usb_clk;
+ logic usb_cs;
+ logic usb_miso;
+ logic [7:0] usb_miosi;
+
+ usb_ft1248 usb_ft1248 (
+ .clk(clk),
+ .reset(reset),
+ .usb_scb(usb_scb),
+ .fifo_bus(fifo_bus),
+ .usb_pwrsav(usb_pwrsav),
+ .usb_clk(usb_clk),
+ .usb_cs(usb_cs),
+ .usb_miso(usb_miso),
+ .usb_miosi(usb_miosi)
+ );
+
+ initial begin
+ clk = 1'b0;
+ forever begin
+ clk = ~clk; #0.5;
+ end
+ end
+
+ initial begin
+ reset = 1'b1;
+ #10;
+ reset = 1'b0;
+ end
+
+ initial begin
+ $dumpfile("traces/usb_ft1248_tb.vcd");
+
+ $dumpvars();
+
+ usb_pwrsav = 1'b1;
+ usb_miso = 1'b1;
+
+ #100;
+
+ fifo_bus.tx_write = 1'b1;
+ #100;
+ fifo_bus.tx_write = 1'b0;
+
+ #103;
+
+ usb_miso = 1'b0;
+ #80;
+ usb_scb.write_buffer_flush = 1'b1;
+ #1;
+ usb_scb.write_buffer_flush = 1'b0;
+ #20;
+ usb_miso = 1'b1;
+ #26;
+ usb_miso = 1'b0;
+
+ #4430;
+
+ usb_miso = 1'b1;
+ #13;
+ usb_miso = 1'b0;
+
+ #79;
+
+ fifo_bus.rx_read = 1'b1;
+ #1;
+ fifo_bus.rx_read = 1'b0;
+
+ #10;
+
+ fifo_bus.rx_read = 1'b1;
+ #1;
+ fifo_bus.rx_read = 1'b0;
+
+ #80;
+
+ fifo_bus.rx_read = 1'b1;
+ #1;
+ fifo_bus.rx_read = 1'b0;
+
+ #200;
+
+ usb_scb.reset_on_ack = 1'b1;
+ #1;
+ usb_scb.reset_on_ack = 1'b0;
+
+ #200;
+
+ usb_scb.reset_off_ack = 1'b1;
+ #1;
+ usb_scb.reset_off_ack = 1'b0;
+
+ #200;
+
+ usb_scb.fifo_flush = 1'b1;
+ #1;
+ usb_scb.fifo_flush = 1'b0;
+
+ #3000;
+
+ usb_scb.fifo_flush = 1'b1;
+ #1;
+ usb_scb.fifo_flush = 1'b0;
+
+ #6000;
+
+ $finish;
+ end
+
+endmodule
diff --git a/fw/tests/mocks/fifo_bus_fifo_mock.sv b/fw/tests/mocks/fifo_bus_fifo_mock.sv
new file mode 100644
index 0000000..2fc57de
--- /dev/null
+++ b/fw/tests/mocks/fifo_bus_fifo_mock.sv
@@ -0,0 +1,145 @@
+module fifo_bus_fifo_mock #(
+ parameter int DEPTH = 1024,
+ parameter int FILL_RATE = 3,
+ parameter int DRAIN_RATE = 3
+) (
+ input clk,
+ input reset,
+
+ fifo_bus.fifo fifo_bus,
+
+ input flush,
+
+ input rx_fill_enabled,
+ input tx_drain_enabled
+);
+
+ localparam int PTR_BITS = $clog2(DEPTH);
+
+
+ // RX FIFO mock
+
+ logic rx_full;
+ logic rx_write;
+ logic [7:0] rx_wdata;
+
+ logic [PTR_BITS:0] rx_count;
+
+ fifo_mock #(
+ .DEPTH(DEPTH)
+ ) fifo_rx (
+ .clk(clk),
+ .reset(reset),
+
+ .empty(fifo_bus.rx_empty),
+ .read(fifo_bus.rx_read),
+ .rdata(fifo_bus.rx_rdata),
+
+ .full(rx_full),
+ .write(rx_write),
+ .wdata(rx_wdata),
+
+ .count(rx_count)
+ );
+
+ localparam int FILL_BITS = $clog2(FILL_RATE);
+ logic [FILL_BITS:0] fill_counter;
+ logic rx_fill;
+
+ always_ff @(posedge clk) begin
+ rx_fill <= rx_fill_enabled;
+ end
+
+ generate;
+ if (FILL_RATE == 0) begin
+ always_comb begin
+ rx_write = rx_fill && !rx_full;
+ end
+ end else begin
+ always_comb begin
+ rx_write = rx_fill && !rx_full && (fill_counter == (FILL_BITS + 1)'(FILL_RATE));
+ end
+ always_ff @(posedge clk) begin
+ if (fill_counter < (FILL_BITS + 1)'(FILL_RATE)) begin
+ fill_counter <= fill_counter + (FILL_BITS + 1)'('d1);
+ end
+ if (reset) begin
+ fill_counter <= (FILL_BITS + 1)'('d0);
+ end else begin
+ if (rx_write) begin
+ fill_counter <= (FILL_BITS + 1)'('d0);
+ end
+ end
+ end
+ end
+ endgenerate
+
+ always_ff @(posedge clk) begin
+ if (reset) begin
+ rx_wdata <= 8'h01;
+ end else begin
+ if (rx_write) begin
+ rx_wdata <= rx_wdata + 8'h01;
+ end
+ end
+ end
+
+
+ // TX FIFO mock
+
+ logic tx_empty;
+ logic tx_read;
+ logic [7:0] tx_rdata;
+
+ logic [PTR_BITS:0] tx_count;
+
+ fifo_mock #(
+ .DEPTH(DEPTH)
+ ) fifo_tx (
+ .clk(clk),
+ .reset(reset),
+
+ .empty(tx_empty),
+ .read(tx_read),
+ .rdata(tx_rdata),
+
+ .full(fifo_bus.tx_full),
+ .write(fifo_bus.tx_write),
+ .wdata(fifo_bus.tx_wdata),
+
+ .count(tx_count)
+ );
+
+ localparam int DRAIN_BITS = $clog2(DRAIN_RATE);
+ logic [DRAIN_BITS:0] drain_counter;
+ logic tx_drain;
+
+ always_ff @(posedge clk) begin
+ tx_drain <= tx_drain_enabled;
+ end
+
+ generate;
+ if (DRAIN_RATE == 0) begin
+ always_comb begin
+ tx_read = tx_drain && !tx_empty;
+ end
+ end else begin
+ always_comb begin
+ tx_read = tx_drain && !tx_empty && (drain_counter == (DRAIN_BITS + 1)'(DRAIN_RATE));
+ end
+ always_ff @(posedge clk) begin
+ if (drain_counter < (DRAIN_BITS + 1)'(DRAIN_RATE)) begin
+ drain_counter <= drain_counter + (DRAIN_BITS + 1)'('d1);
+ end
+ if (reset) begin
+ drain_counter <= (DRAIN_BITS + 1)'('d0);
+ end else begin
+ if (tx_read) begin
+ drain_counter <= (DRAIN_BITS + 1)'('d0);
+ end
+ end
+ end
+ end
+ endgenerate
+
+endmodule
diff --git a/fw/tests/mocks/fifo_bus_mock.sv b/fw/tests/mocks/fifo_bus_mock.sv
deleted file mode 100644
index bfa2a1c..0000000
--- a/fw/tests/mocks/fifo_bus_mock.sv
+++ /dev/null
@@ -1,173 +0,0 @@
-module fifo_bus_mock #(
- parameter int DEPTH = 1024,
- parameter int FILL_RATE = 3,
- parameter int DRAIN_RATE = 3
-) (
- input clk,
- input reset,
-
- fifo_bus.fifo fifo_bus,
-
- input flush,
-
- input rx_fill_enabled,
- input tx_drain_enabled
-);
-
- localparam int PTR_BITS = $clog2(DEPTH);
-
-
- // RX FIFO mock
-
- logic [7:0] rx_fifo_mem [0:(DEPTH - 1)];
- logic [(PTR_BITS - 1):0] rx_fifo_rptr;
- logic [(PTR_BITS - 1):0] rx_fifo_wptr;
- logic [PTR_BITS:0] rx_available;
- logic rx_fifo_full;
- logic rx_fifo_almost_full;
- logic rx_write;
- logic [7:0] rx_wdata;
-
- always_comb begin
- rx_fifo_full = rx_available >= (PTR_BITS + 1)'(DEPTH);
- rx_fifo_almost_full = rx_available >= (PTR_BITS + 1)'(DEPTH - 1);
- fifo_bus.rx_empty = rx_available == (PTR_BITS + 1)'('d0);
- fifo_bus.rx_almost_empty = rx_available <= (PTR_BITS + 1)'('d1);
- end
-
- always_ff @(posedge clk) begin
- if (fifo_bus.rx_read) begin
- fifo_bus.rx_rdata <= rx_fifo_mem[rx_fifo_rptr];
- rx_fifo_rptr <= rx_fifo_rptr + PTR_BITS'('d1);
- rx_available <= rx_available - (PTR_BITS + 1)'('d1);
- end
- if (rx_write) begin
- rx_fifo_mem[rx_fifo_wptr] <= rx_wdata;
- rx_fifo_wptr <= rx_fifo_wptr + PTR_BITS'('d1);
- rx_available <= rx_available + (PTR_BITS + 1)'('d1);
- end
- if (fifo_bus.rx_read && rx_write) begin
- rx_available <= rx_available;
- end
- if (reset || flush) begin
- rx_available <= (PTR_BITS + 1)'('d0);
- rx_fifo_rptr <= PTR_BITS'('d0);
- rx_fifo_wptr <= PTR_BITS'('d0);
- end
- end
-
- localparam int FILL_BITS = $clog2(FILL_RATE);
- logic [FILL_BITS:0] fill_counter;
- logic rx_fill;
-
- always_ff @(posedge clk) begin
- rx_fill <= rx_fill_enabled;
- end
-
- generate;
- if (FILL_RATE == 0) begin
- always_comb begin
- rx_write = rx_fill && !rx_fifo_full;
- end
- end else begin
- always_comb begin
- rx_write = rx_fill && !rx_fifo_full && (fill_counter == (FILL_BITS + 1)'(FILL_RATE));
- end
- always_ff @(posedge clk) begin
- if (fill_counter < (FILL_BITS + 1)'(FILL_RATE)) begin
- fill_counter <= fill_counter + (FILL_BITS + 1)'('d1);
- end
- if (reset) begin
- fill_counter <= (FILL_BITS + 1)'('d0);
- end else begin
- if (rx_write) begin
- fill_counter <= (FILL_BITS + 1)'('d0);
- end
- end
- end
- end
- endgenerate
-
- always_ff @(posedge clk) begin
- if (reset) begin
- rx_wdata <= 8'h01;
- end else begin
- if (rx_write) begin
- rx_wdata <= rx_wdata + 8'h01;
- end
- end
- end
-
-
- // TX FIFO mock
-
- logic [7:0] tx_fifo_mem [0:(DEPTH - 1)];
- logic [(PTR_BITS - 1):0] tx_fifo_rptr;
- logic [(PTR_BITS - 1):0] tx_fifo_wptr;
- logic [PTR_BITS:0] tx_available;
- logic tx_fifo_empty;
- logic tx_fifo_almost_empty;
- logic tx_read;
- logic [7:0] tx_rdata;
-
- always_comb begin
- tx_fifo_empty = tx_available == (PTR_BITS + 1)'('d0);
- tx_fifo_almost_empty = tx_available <= (PTR_BITS + 1)'('d1);
- fifo_bus.tx_full = tx_available >= (PTR_BITS + 1)'(DEPTH);
- fifo_bus.tx_almost_full = tx_available >= (PTR_BITS + 1)'(DEPTH - 1);
- end
-
- always_ff @(posedge clk) begin
- if (fifo_bus.tx_write) begin
- tx_fifo_mem[tx_fifo_wptr] <= fifo_bus.tx_wdata;
- tx_fifo_wptr <= tx_fifo_wptr + PTR_BITS'('d1);
- tx_available <= tx_available + (PTR_BITS + 1)'('d1);
- end
- if (tx_read) begin
- tx_rdata <= tx_fifo_mem[tx_fifo_rptr];
- tx_fifo_rptr <= tx_fifo_rptr + PTR_BITS'('d1);
- tx_available <= tx_available - (PTR_BITS + 1)'('d1);
- end
- if (fifo_bus.tx_write && tx_read) begin
- tx_available <= tx_available;
- end
- if (reset || flush) begin
- tx_available <= (PTR_BITS + 1)'('d0);
- tx_fifo_rptr <= PTR_BITS'('d0);
- tx_fifo_wptr <= PTR_BITS'('d0);
- end
- end
-
- localparam int DRAIN_BITS = $clog2(DRAIN_RATE);
- logic [DRAIN_BITS:0] drain_counter;
- logic tx_drain;
-
- always_ff @(posedge clk) begin
- tx_drain <= tx_drain_enabled;
- end
-
- generate;
- if (DRAIN_RATE == 0) begin
- always_comb begin
- tx_read = tx_drain && !tx_fifo_empty;
- end
- end else begin
- always_comb begin
- tx_read = tx_drain && !tx_fifo_empty && (drain_counter == (DRAIN_BITS + 1)'(DRAIN_RATE));
- end
- always_ff @(posedge clk) begin
- if (drain_counter < (DRAIN_BITS + 1)'(DRAIN_RATE)) begin
- drain_counter <= drain_counter + (DRAIN_BITS + 1)'('d1);
- end
- if (reset) begin
- drain_counter <= (DRAIN_BITS + 1)'('d0);
- end else begin
- if (tx_read) begin
- drain_counter <= (DRAIN_BITS + 1)'('d0);
- end
- end
- end
- end
- endgenerate
-
-endmodule
diff --git a/fw/tests/mocks/fifo_mock.sv b/fw/tests/mocks/fifo_mock.sv
new file mode 100644
index 0000000..acf9065
--- /dev/null
+++ b/fw/tests/mocks/fifo_mock.sv
@@ -0,0 +1,49 @@
+module fifo_mock #(
+ parameter int DEPTH = 1024,
+ localparam int PTR_BITS = $clog2(DEPTH)
+) (
+ input clk,
+ input reset,
+
+ output logic empty,
+ input read,
+ output [7:0] rdata,
+
+ output logic full,
+ input write,
+ input [7:0] wdata,
+
+ output logic [PTR_BITS:0] count
+);
+
+ logic [7:0] fifo_mem [0:(DEPTH - 1)];
+ logic [(PTR_BITS - 1):0] fifo_rptr;
+ logic [(PTR_BITS - 1):0] fifo_wptr;
+
+ always_comb begin
+ full = count >= (PTR_BITS + 1)'(DEPTH);
+ empty = count == (PTR_BITS + 1)'('d0);
+ end
+
+ always_ff @(posedge clk) begin
+ if (read) begin
+ rdata <= fifo_mem[fifo_rptr];
+ fifo_rptr <= fifo_rptr + PTR_BITS'('d1);
+ count <= count - (PTR_BITS + 1)'('d1);
+ end
+ if (write) begin
+ fifo_mem[fifo_wptr] <= wdata;
+ fifo_wptr <= fifo_wptr + PTR_BITS'('d1);
+ count <= count + (PTR_BITS + 1)'('d1);
+ end
+ if (read && write) begin
+ count <= count;
+ end
+ if (reset) begin
+ count <= (PTR_BITS + 1)'('d0);
+ fifo_rptr <= PTR_BITS'('d0);
+ fifo_wptr <= PTR_BITS'('d0);
+ end
+ end
+
+endmodule
diff --git a/fw/tests/mocks/vendor/fifo_8kb.sv b/fw/tests/mocks/vendor/fifo_8kb.sv
new file mode 100644
index 0000000..f20105b
--- /dev/null
+++ b/fw/tests/mocks/vendor/fifo_8kb.sv
@@ -0,0 +1,33 @@
+module fifo_8kb (
+ input clk,
+ input reset,
+
+ output empty,
+ input read,
+ output [7:0] rdata,
+
+ output full,
+ input write,
+ input [7:0] wdata,
+
+ output logic [10:0] count
+);
+
+ fifo_mock #(
+ .DEPTH(1024)
+ ) fifo_8kb (
+ .clk(clk),
+ .reset(reset),
+
+ .empty(empty),
+ .read(read),
+ .rdata(rdata),
+
+ .full(full),
+ .write(write),
+ .wdata(wdata),
+
+ .count(count)
+ );
+
+endmodule