upsilon/gateware/rtl/raster/raster_sim.v

206 lines
4.7 KiB
Coq
Raw Normal View History

2023-06-15 12:24:35 -04:00
/* Copyright 2023 (C) Peter McGoron
* This file is a part of Upsilon, a free and open source software project.
* For license terms, refer to the files in `doc/copying` in the Upsilon
* source distribution.
*/
2022-12-16 19:46:04 -05:00
`timescale 10ns/10ns
`include "raster_cmds.vh"
`include "ram_shim_cmds.vh"
2022-11-26 12:00:10 -05:00
module raster_sim #(
parameter DAC_WAIT_BETWEEN_CMD = 10,
parameter DAT_WID = 24,
parameter RAM_WORD = 16,
2022-12-16 19:46:04 -05:00
parameter RAM_WID = 32,
2022-12-23 15:22:48 -05:00
parameter RAM_SIM_WAIT_TIME = 72,
2022-12-16 19:46:04 -05:00
parameter ADC_SIM_WAIT_TIME = 54
2022-11-26 12:00:10 -05:00
) (
input clk,
2022-12-23 15:22:48 -05:00
output is_running,
input [`RASTER_CMD_WID-1:0] kernel_cmd,
input [`RASTER_DATA_WID-1:0] kernel_data_in,
output [`RASTER_DATA_WID-1:0] kernel_data_out,
input kernel_ready,
output kernel_finished,
2022-12-23 15:22:48 -05:00
output [`DAC_DATA_WID-1:0] x_dac,
output [`DAC_DATA_WID-1:0] y_dac,
2022-12-23 15:22:48 -05:00
output reg [`ADCNUM-1:0] adc_arm,
input [`MAX_ADC_DATA_WID-1:0] adc_data [`ADCNUM-1:0],
input [`ADCNUM-1:0] adc_finished,
2022-11-26 12:00:10 -05:00
/* DMA interface */
output [RAM_WORD-1:0] word,
output [RAM_WID-1:0] addr,
2022-12-16 19:46:04 -05:00
output reg ram_write,
input ram_valid,
/* RAM shim control interface */
input [RAM_WID-1:0] shim_cmd_data,
input [`RAM_SHIM_CMD_WID-1:0] shim_cmd,
input shim_cmd_active,
output shim_cmd_finished,
output [RAM_WID-1:0] shim_cmd_data_out
2022-11-26 12:00:10 -05:00
);
/**** DAC simulation.
* The code to handle each axis (X and Y) are similar.
****/
2022-12-16 19:46:04 -05:00
2022-12-23 15:22:48 -05:00
reg [`DAC_WID-1:0] coord_write_buf [1:0];
/* verilator lint_off UNUSEDSIGNAL */
reg [`DAC_WID-1:0] coord_to_dac [1:0];
/* verilator lint_on UNUSEDSIGNAL */
reg [`DAC_WID-1:0] coord_from_dac [1:0];
2022-12-16 19:46:04 -05:00
wire coord_arm [1:0];
reg coord_finished [1:0];
2022-12-23 15:22:48 -05:00
reg [`DAC_DATA_WID-1:0] coord_dac [1:0];
assign x_dac = coord_dac[0];
assign y_dac = coord_dac[1];
2022-12-16 19:46:04 -05:00
genvar ci;
generate for (ci = 0; ci < 2; ci = ci + 1) begin
initial begin
coord_write_buf[ci] = 0;
coord_to_dac[ci] = 0;
coord_from_dac[ci] = 0;
coord_finished[ci] = 0;
end
always @ (posedge clk) begin
if (coord_arm[ci] && !coord_finished[ci]) begin
coord_to_dac[ci] <= coord_write_buf[ci];
coord_finished[ci] <= 1;
2022-12-23 15:22:48 -05:00
case (coord_from_dac[ci][`DAC_WID-1:`DAC_DATA_WID])
2022-12-16 19:46:04 -05:00
4'b1001: begin
coord_write_buf[ci] <= {4'b1001, coord_dac[ci]};
end
4'b0001: begin
coord_write_buf[ci] <= 0;
2022-12-23 15:22:48 -05:00
coord_dac[ci] <= coord_from_dac[ci][`DAC_DATA_WID-1:0];
2022-12-16 19:46:04 -05:00
end
default: ;
2022-12-16 19:46:04 -05:00
endcase
end else if (!coord_arm[ci]) begin
coord_finished[ci] <= 0;
end
end
end endgenerate
/**** ADC Shim
* This shim and the shim below implement delays to simulate the actual
* acquisition process. The values are then floated up to the Verilator
* simulator so the C++ code doesn't have to implement timers manually.
****/
2022-12-16 19:46:04 -05:00
2022-12-23 15:22:48 -05:00
wire [`ADCNUM-1:0] adc_arm_internal;
2022-12-16 19:46:04 -05:00
reg [31:0] adc_wait_cntr = 0;
always @ (posedge clk) begin
if (adc_arm_internal != 0) begin
if (adc_wait_cntr < ADC_SIM_WAIT_TIME) begin
adc_wait_cntr <= adc_wait_cntr + 1;
end else begin
adc_arm <= adc_arm_internal;
end
end else begin
adc_wait_cntr <= 0;
2022-12-23 15:22:48 -05:00
adc_arm <= 0;
2022-12-16 19:46:04 -05:00
end
end
/**** RAM Shim ****/
wire ram_write_internal;
reg [31:0] ram_wait_cntr = 0;
2022-12-16 19:46:04 -05:00
always @ (posedge clk) begin
if (!ram_write_internal) begin
ram_wait_cntr <= 0;
2022-12-23 15:22:48 -05:00
ram_write <= 0;
end else if (ram_wait_cntr < RAM_SIM_WAIT_TIME) begin
ram_wait_cntr <= ram_wait_cntr + 1;
2022-12-16 19:46:04 -05:00
end else begin
ram_write <= 1;
2022-12-16 19:46:04 -05:00
end
end
2022-12-23 15:22:48 -05:00
wire [`MAX_ADC_DATA_WID-1:0] ram_data;
wire ram_commit;
wire ram_finished;
2022-11-26 12:00:10 -05:00
ram_shim #(
.DAT_WID(DAT_WID),
.RAM_WORD(RAM_WORD),
.RAM_WID(RAM_WID)
) ram (
.clk(clk),
.rst(0),
2022-11-26 12:00:10 -05:00
.data(ram_data),
.data_commit(ram_commit),
.finished(ram_finished),
2022-11-26 12:00:10 -05:00
.word(word),
.addr(addr),
2022-12-16 19:46:04 -05:00
.write(ram_write_internal),
.valid(ram_valid),
.cmd_data(shim_cmd_data),
.cmd(shim_cmd),
.cmd_active(shim_cmd_active),
.cmd_finished(shim_cmd_finished),
.cmd_data_out(shim_cmd_data_out)
2022-11-26 12:00:10 -05:00
);
/* Converting array to vector, arrays are easier to handle in Verilator. */
2022-12-23 15:22:48 -05:00
wire [`ADCNUM*`MAX_ADC_DATA_WID-1:0] adc_data_internal;
genvar ii;
2022-12-23 15:22:48 -05:00
generate for (ii = 0; ii < `ADCNUM; ii = ii + 1) begin
assign adc_data_internal[(ii+1)*`MAX_ADC_DATA_WID-1:ii*`MAX_ADC_DATA_WID]
= adc_data[ii];
end endgenerate
2022-11-26 12:00:10 -05:00
raster #(
2022-12-23 15:22:48 -05:00
.DAC_WAIT_BETWEEN_CMD(DAC_WAIT_BETWEEN_CMD)
2022-11-26 12:00:10 -05:00
) raster (
.clk(clk),
2022-12-23 15:22:48 -05:00
.is_running(is_running),
.kernel_cmd(kernel_cmd),
.kernel_data_in(kernel_data_in),
.kernel_data_out(kernel_data_out),
.kernel_ready(kernel_ready),
.kernel_finished(kernel_finished),
.x_arm(coord_arm[0]),
.x_to_dac(coord_to_dac[0]),
.x_from_dac(coord_from_dac[0]),
.x_finished(coord_finished[0]),
.y_arm(coord_arm[1]),
.y_to_dac(coord_to_dac[1]),
.y_from_dac(coord_from_dac[1]),
.y_finished(coord_finished[1]),
2022-11-26 12:00:10 -05:00
2022-12-16 19:46:04 -05:00
.adc_arm(adc_arm_internal),
.adc_data(adc_data_internal),
2022-11-26 12:00:10 -05:00
.adc_finished(adc_finished),
.data(ram_data),
.mem_commit(ram_commit),
.mem_finished(ram_finished)
2022-11-26 12:00:10 -05:00
);
2022-12-23 15:22:48 -05:00
initial begin
$dumpfile("raster.fst");
$dumpvars;
end
2022-11-26 12:00:10 -05:00
endmodule
`undefineall