upsilon/firmware/rtl/waveform/dma_sim.v

45 lines
1.2 KiB
Verilog

/* This module is used to simulate direct memory access, where only
* a small amount of memory is valid to read.
*/
module dma_sim #(
parameter RAM_WID = 32,
parameter RAM_WORD_WID = 16,
parameter RAM_REAL_START = 32'h12340,
parameter RAM_CNTR_LEN = 12,
parameter TOTAL_RAM_WORD_MINUS_ONE = 4095,
parameter DELAY_CNTR_LEN = 8,
parameter DELAY_TOTAL = 12
) (
input clk,
/* DMA interface */
input [RAM_WID-1:0] ram_dma_addr,
output reg [RAM_WORD_WID-1:0] ram_word,
input ram_read,
output reg ram_valid,
/*- Verilator interface */
input [RAM_WORD_WID-1:0] backing_store[TOTAL_RAM_WORD_MINUS_ONE:0]
);
reg [DELAY_CNTR_LEN-1:0] delay_cntr = 0;
always @ (posedge clk) begin
if (!ram_read) begin
delay_cntr <= 0;
ram_valid <= 0;
end else if (delay_cntr < DELAY_TOTAL) begin
delay_cntr <= delay_cntr + 1;
end else if (!ram_valid) begin
if (ram_dma_addr < RAM_REAL_START || ram_dma_addr > RAM_REAL_START + 2*TOTAL_RAM_WORD_MINUS_ONE) begin
$display("ram_dma_addr %x out of bounds", ram_dma_addr);
$stop();
end else begin
ram_word <= backing_store[(RAM_CNTR_LEN)'((ram_dma_addr - RAM_REAL_START)/2)];
ram_valid <= 1;
end
end
end
endmodule