SummerCart64/fw/tests/mocks/fifo_bus_fifo_mock.sv

146 lines
3.4 KiB
Systemverilog

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