SummerCart64/fw/tests/mocks/fifo_bus_mock.sv
Mateusz Faderewski 24f04ae916 verilator init
2024-07-07 00:09:03 +02:00

173 lines
5.3 KiB
Systemverilog

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