From 96e9a3d043b9a1217e3470882ed3a8fec91a8325 Mon Sep 17 00:00:00 2001 From: Peter McGoron Date: Fri, 23 Dec 2022 20:22:48 +0000 Subject: [PATCH] raster simulate --- firmware/rtl/raster/Makefile | 20 ++- firmware/rtl/raster/raster.v | 117 +++++++-------- firmware/rtl/raster/raster_cmds.vh | 16 ++- firmware/rtl/raster/raster_sim.cpp | 223 ++++++++++++++++++++++------- firmware/rtl/raster/raster_sim.v | 60 ++++---- 5 files changed, 292 insertions(+), 144 deletions(-) diff --git a/firmware/rtl/raster/Makefile b/firmware/rtl/raster/Makefile index 1c85bb9..445f914 100644 --- a/firmware/rtl/raster/Makefile +++ b/firmware/rtl/raster/Makefile @@ -3,7 +3,7 @@ .PHONY: test clean -test: obj_dir/Vram_fifo obj_dir/Vram_shim +test: obj_dir/Vram_fifo obj_dir/Vram_shim obj_dir/Vraster_sim RAM_FIFO_SRC= ram_fifo.v ram_fifo_dual_port.v ram_fifo_sim.cpp obj_dir/Vram_fifo.mk: ${RAM_FIFO_SRC} @@ -11,7 +11,7 @@ obj_dir/Vram_fifo.mk: ${RAM_FIFO_SRC} ${RAM_FIFO_SRC} obj_dir/Vram_fifo: obj_dir/Vram_fifo.mk cd obj_dir && make -f Vram_fifo.mk - @./obj_dir/Vram_fifo && echo 'Vram_fifo successful' + @./obj_dir/Vram_fifo && echo 'ram_fifo successful' RAM_SHIM_SRC= ram_shim.v ram_fifo.v ram_fifo_dual_port.v ram_shim_sim.cpp obj_dir/Vram_shim.mk: ${RAM_SHIM_SRC} ram_shim_cmds.vh ram_shim_cmds.h @@ -20,14 +20,26 @@ obj_dir/Vram_shim.mk: ${RAM_SHIM_SRC} ram_shim_cmds.vh ram_shim_cmds.h ${RAM_SHIM_SRC} obj_dir/Vram_shim: obj_dir/Vram_shim.mk ram_shim_sim.cpp cd obj_dir && make -f Vram_shim.mk - @./obj_dir/Vram_shim && echo 'Vram_shim successful' + @./obj_dir/Vram_shim && echo 'ram_shim successful' + +RASTER_SIM_SRC = raster_sim.v raster.v ram_shim.v ram_fifo.v ram_fifo_dual_port.v raster_sim.cpp + +obj_dir/Vraster_sim.mk: ${RASTER_SIM_SRC} raster_cmds.vh raster_cmds.h ram_shim_cmds.vh ram_shim_cmds.h + verilator --cc --exe -Wall --trace --trace-fst -CFLAGS -Wall \ + ${RASTER_SIM_SRC} +obj_dir/Vraster_sim: obj_dir/Vraster_sim.mk raster_sim.cpp + cd obj_dir && make -f Vraster_sim.mk + @./obj_dir/Vraster_sim && echo 'raster successful' ####### Codegen ######## ram_shim_cmds.h: ram_shim_cmds.vh echo '#pragma once' > ram_shim_cmds.h sed 's/`define/#define/g; s/`//g' ram_shim_cmds.vh >> ram_shim_cmds.h +raster_cmds.h: raster_cmds.vh + echo '#pragma once' > raster_cmds.h + sed 's/`define/#define/g; s/`//g' raster_cmds.vh >> raster_cmds.h clean: rm -rf obj_dir - rm *.vcd ram_shim_cmds.h + rm -f *.vcd ram_shim_cmds.h diff --git a/firmware/rtl/raster/raster.v b/firmware/rtl/raster/raster.v index 3d4d11d..1386f00 100644 --- a/firmware/rtl/raster/raster.v +++ b/firmware/rtl/raster/raster.v @@ -8,50 +8,50 @@ `include "raster_cmds.vh" `timescale 10ns/10ns module raster #( - parameter SAMPLEWID = 9, - parameter DAC_DATA_WID = 20, - parameter DAC_WID = 24, - parameter DAC_WAIT_BETWEEN_CMD = 10, - parameter TIMER_WID = 4, - parameter STEPWID = 16, - parameter ADCNUM = 9, - parameter MAX_ADC_DATA_WID = 24 + parameter DAC_WAIT_BETWEEN_CMD = 10 ) ( input clk, +`ifdef VERILATOR + output is_running, +`endif /* Kernel interface. */ input [`RASTER_CMD_WID-1:0] kernel_cmd, + /* verilator lint_off UNUSEDSIGNAL */ input [`RASTER_DATA_WID-1:0] kernel_data_in, + /* verilator lint_on UNUSEDSIGNAL */ output reg [`RASTER_DATA_WID-1:0] kernel_data_out, input kernel_ready, output reg kernel_finished, /* X and Y DAC piezos */ output x_arm, - output [DAC_WID-1:0] x_to_dac, + output [`DAC_WID-1:0] x_to_dac, /* verilator lint_off UNUSED */ - input [DAC_WID-1:0] x_from_dac, + input [`DAC_WID-1:0] x_from_dac, + /* verilator lint_on UNUSED */ input x_finished, output y_arm, - output [DAC_WID-1:0] y_to_dac, + output [`DAC_WID-1:0] y_to_dac, /* verilator lint_off UNUSED */ - input [DAC_WID-1:0] y_from_dac, + input [`DAC_WID-1:0] y_from_dac, + /* verilator lint_on UNUSED */ input y_finished, /* Connections to all possible ADCs. These are connected to SPI masters * and they will automatically extend ADC value lengths to their highest * values. */ - output reg [ADCNUM-1:0] adc_arm, + output reg [`ADCNUM-1:0] adc_arm, /* Yosys does not support input arrays. */ - input [ADCNUM*MAX_ADC_DATA_WID-1:0] adc_data, - input [ADCNUM-1:0] adc_finished, + input [`ADCNUM*`MAX_ADC_DATA_WID-1:0] adc_data, + input [`ADCNUM-1:0] adc_finished, /* RAM DMA. This is generally not directly connected to the * DMA IP. A shim is used in order to write multiple words * to memory. */ - output reg [MAX_ADC_DATA_WID-1:0] data, + output reg [`MAX_ADC_DATA_WID-1:0] data, output reg mem_commit, input mem_finished ); @@ -101,43 +101,45 @@ module raster #( */ localparam WAIT_ON_ARM = 0; -localparam GET_DAC_VALUES = 1; -localparam REQUEST_DAC_VALUES = 2; -localparam MEASURE = 3; -localparam SCAN_ADC_VALUES = 4; -localparam ADVANCE_DAC_WRITE = 5; -localparam WAIT_ADVANCE = 6; +localparam REQUEST_DAC_VALUES = 1; +localparam GET_DAC_VALUES = 2; +localparam WAIT_ADVANCE = 3; +localparam MEASURE = 4; +localparam SCAN_ADC_VALUES = 5; +localparam ADVANCE_DAC_WRITE = 6; localparam NEXT_LINE = 7; localparam WAIT_ON_ARM_DEASSERT = 8; localparam STATE_WID = 4; /********** Loop State ***********/ reg [STATE_WID-1:0] state = WAIT_ON_ARM; -reg [SAMPLEWID-1:0] sample = 0; -reg [SAMPLEWID-1:0] line = 0; -reg [TIMER_WID-1:0] counter = 0; -reg signed [DAC_DATA_WID-1:0] x_val = 0; -reg signed [DAC_DATA_WID-1:0] y_val = 0; +reg [`SAMPLEWID-1:0] sample = 0; +reg [`SAMPLEWID-1:0] line = 0; +reg [`TIMERWID-1:0] counter = 0; +reg signed [`DAC_DATA_WID-1:0] x_val = 0; +reg signed [`DAC_DATA_WID-1:0] y_val = 0; /* Buffer to store all measured ADC values. This * is shifted until it is all zeros to determine * which ADC values should be read off. */ -reg [ADCNUM-1:0] adc_used_tmp = 0; -reg [ADCNUM*MAX_ADC_DATA_WID-1:0] adc_data_tmp = 0; +reg [`ADCNUM-1:0] adc_used_tmp = 0; +reg [`ADCNUM*`MAX_ADC_DATA_WID-1:0] adc_data_tmp = 0; /********** Loop Parameters *************/ -reg [ADCNUM-1:0] adc_used = 0; +reg [`ADCNUM-1:0] adc_used = 0; reg is_reverse = 0; reg arm = 0; reg running = 0; -reg signed [DAC_DATA_WID-1:0] dx = 0; -reg signed [DAC_DATA_WID-1:0] dy = 0; -reg [TIMER_WID-1:0] settle_time = 0; +`ifdef VERILATOR +assign is_running = running; +`endif +reg signed [`DAC_DATA_WID-1:0] dx = 0; +reg signed [`DAC_DATA_WID-1:0] dy = 0; +reg [`TIMERWID-1:0] settle_time = 0; -reg [SAMPLEWID-1:0] max_samples = 0; -reg [SAMPLEWID-1:0] max_lines = 0; -reg [STEPWID-1:0] steps_per_sample = 0; +reg [`SAMPLEWID-1:0] max_samples = 0; +reg [`SAMPLEWID-1:0] max_lines = 0; /********** Control Interface ************ * This code assumes that RASTER_DATA_WID is greater than all registers. @@ -161,25 +163,26 @@ end // Generates code to handle write requests from the kernel. `define generate_register(code, width, register) \ `generate_register_read(code, width, register) \ -code | `RASTER_WRITE_BIT: begin \ - if (!running && (code) != `RASTER_ARM) begin \ +code | `RASTER_WRITE_BIT: \ + if (!running || (code) == `RASTER_ARM) begin \ register <= kernel_data_in[(width)-1:0]; \ kernel_finished <= 1; \ - end \ -end + end always @ (posedge clk) begin if (!kernel_ready) kernel_finished <= 0; else if (kernel_ready) begin case (kernel_cmd) - `generate_register(`RASTER_MAX_SAMPLES, SAMPLEWID, max_samples) - `generate_register(`RASTER_MAX_LINES, SAMPLEWID, max_lines) - `generate_register(`RASTER_SETTLE_TIME, TIMER_WID, settle_time) - `generate_register(`RASTER_DX, DAC_DATA_WID, dx) - `generate_register(`RASTER_DY, DAC_DATA_WID, dy) - `generate_register(`RASTER_USED_ADCS, ADCNUM, adc_used) - `generate_register(`RASTER_STEPS_PER_SAMPLE, STEPWID, steps_per_sample) + `generate_register(`RASTER_MAX_SAMPLES, `SAMPLEWID, max_samples) + `generate_register(`RASTER_MAX_LINES, `SAMPLEWID, max_lines) + `generate_register(`RASTER_SETTLE_TIME, `TIMERWID, settle_time) + `generate_register(`RASTER_DX, `DAC_DATA_WID, dx) + `generate_register(`RASTER_DY, `DAC_DATA_WID, dy) + `generate_register(`RASTER_USED_ADCS, `ADCNUM, adc_used) `generate_register(`RASTER_ARM, 1, arm) `generate_register_read(`RASTER_RUNNING, 1, running) +`ifdef VERILATOR + default: $error("unknown kernel message"); +`endif endcase end end `undef generate_register_read @@ -234,8 +237,8 @@ always @ (posedge clk) begin x_arm <= 1; y_arm <= 1; end else if (x_finished && y_finished) begin - x_val <= x_from_dac[DAC_DATA_WID-1:0]; - y_val <= y_from_dac[DAC_DATA_WID-1:0]; + x_val <= x_from_dac[`DAC_DATA_WID-1:0]; + y_val <= y_from_dac[`DAC_DATA_WID-1:0]; x_arm <= 0; y_arm <= 0; @@ -262,7 +265,7 @@ always @ (posedge clk) begin end SCAN_ADC_VALUES: if (adc_used_tmp == 0 && !mem_commit) begin `CHECK_DAC_ARM - if (sample == max_samples) begin + if (sample == max_samples-1) begin dx <= ~dx + 1; dy <= ~dy + 1; @@ -275,6 +278,7 @@ always @ (posedge clk) begin is_reverse <= !is_reverse; sample <= 0; end else begin + sample <= sample + 1; state <= ADVANCE_DAC_WRITE; end end else if (mem_finished) begin @@ -284,9 +288,9 @@ always @ (posedge clk) begin end else begin `CHECK_DAC_ARM adc_used_tmp <= adc_used_tmp << 1; - adc_data_tmp <= adc_data_tmp << MAX_ADC_DATA_WID; - if (adc_used_tmp[ADCNUM-1]) begin - data <= adc_data_tmp[ADCNUM*MAX_ADC_DATA_WID-1:(ADCNUM-1)*MAX_ADC_DATA_WID]; + adc_data_tmp <= adc_data_tmp << `MAX_ADC_DATA_WID; + if (adc_used_tmp[`ADCNUM-1]) begin + data <= adc_data_tmp[`ADCNUM*`MAX_ADC_DATA_WID-1:(`ADCNUM-1)*`MAX_ADC_DATA_WID]; mem_commit <= 1; end end @@ -298,7 +302,6 @@ always @ (posedge clk) begin y_to_dac <= {4'b0001, y_val + dy}; x_arm <= 1; y_arm <= 1; - sample <= sample + 1; end else if (x_finished && y_finished) begin counter <= 0; state <= WAIT_ADVANCE; @@ -306,10 +309,10 @@ always @ (posedge clk) begin y_arm <= 0; end NEXT_LINE: if (!x_arm || !y_arm) begin - if (line == max_lines) begin + if (line == max_lines-1) begin state <= WAIT_ON_ARM_DEASSERT; - running <= 0; end else begin + sample <= 0; /* rotation of (dx,dy) by 90° -> (dy, -dx) */ x_val <= x_val + dy; x_to_dac <= {4'b0001, x_val + dy}; @@ -327,6 +330,8 @@ always @ (posedge clk) begin end WAIT_ON_ARM_DEASSERT: if (!arm) begin state <= WAIT_ON_ARM; + end else begin + running <= 0; end endcase end diff --git a/firmware/rtl/raster/raster_cmds.vh b/firmware/rtl/raster/raster_cmds.vh index f49c425..8ae67c8 100644 --- a/firmware/rtl/raster/raster_cmds.vh +++ b/firmware/rtl/raster/raster_cmds.vh @@ -1,6 +1,3 @@ -/* Make sure there are no gaps! The code generator will not work - * correctly. - */ `define RASTER_NOOP 0 `define RASTER_MAX_SAMPLES 1 `define RASTER_MAX_LINES 2 @@ -9,11 +6,20 @@ `define RASTER_DY 5 `define RASTER_ARM 6 `define RASTER_USED_ADCS 7 -`define RASTER_STEPS_PER_SAMPLE 8 -`define RASTER_RUNNING 9 +`define RASTER_RUNNING 8 `define RASTER_WRITE_BIT (1 << (`RASTER_CMD_WID - 1)) `define RASTER_CMD_WID 8 `define RASTER_DATA_WID 32 + +/* Instead of using parameters, these values are preprocessor + * defines so that they may be reference in kernel code. + */ +`define SAMPLEWID 16 +`define DAC_DATA_WID 20 +`define DAC_WID 24 +`define TIMERWID 8 +`define ADCNUM 9 +`define MAX_ADC_DATA_WID 24 diff --git a/firmware/rtl/raster/raster_sim.cpp b/firmware/rtl/raster/raster_sim.cpp index 8022c21..81fb255 100644 --- a/firmware/rtl/raster/raster_sim.cpp +++ b/firmware/rtl/raster/raster_sim.cpp @@ -1,25 +1,57 @@ -#include #include #include #include #include +#include #include -#include #include - #include + +#include "ram_shim_cmds.h" +#include "raster_cmds.h" #include "Vraster_sim.h" using ModType = Vraster_sim; ModType *mod; uint32_t main_time = 0; +double sc_time_stamp() { + return main_time; +} + +static void _assert(const char *file, int line, const char *exp, bool ev, const char *fmt, ...) { + if (!ev) { + va_list va; + va_start(va, fmt); + fprintf(stderr, "%s:%d: assertion failed: %s\n", file, line, exp); + vfprintf(stderr, fmt, va); + fprintf(stderr, "\n"); + va_end(va); + exit(1); + } +} + +#define STRINGIFY(s) #s +/* ,##__VA_ARGS__ is a GNU C extension */ +#define my_assert(e, fmt, ...) _assert(__FILE__, __LINE__, STRINGIFY(e), (e), fmt ,##__VA_ARGS__) + static void run_clock() { +#ifdef BAILOUT + static int iters = 0; +#endif for (int i = 0; i < 2; i++) { mod->clk = !mod->clk; mod->eval(); main_time++; +#ifdef BAILOUT + iters++; +#endif } + +#ifdef BAILOUT + if (iters >= 1000000) + exit(2); +#endif } static void cleanup_exit() { @@ -33,76 +65,171 @@ static void init(int argc, char **argv) { mod = new ModType; mod->clk = 0; atexit(cleanup_exit); + + char *seed = getenv("RANDOM_SEED"); + if (seed) { + unsigned long i = strtoul(seed, NULL, 10); + srand((unsigned int)i); + } } +using V = uint32_t; + +// Verilator makes all ports unsigned, even when marked as signed in +// Verilog. +V sign_extend(V x, unsigned len, bool is_signed) { + if (!is_signed) + return x; + // if high bit is 1 + if (x >> (len - 1) & 1) { + // This mask selects all bits below the highest bit. + // By inverting it, it selects the highest bit, and all + // higher bits that must be sign extended. + V mask = (1 << len) - 1; + // Set all high bits to 1. The mask has all bits lower + // than the highest bit 0, so the bits in "x" pass through. + return ~mask | x; + } else { + return x; + } +} + +static int32_t read_raster_reg(int reg, unsigned siz, bool is_signed) { + mod->kernel_cmd = reg; + mod->kernel_ready = 1; + while (!mod->kernel_finished) + run_clock(); + mod->kernel_ready = 0; + run_clock(); + + return sign_extend(mod->kernel_data_out, siz, is_signed); +} + +static int32_t write_raster_reg(int reg, unsigned siz, int32_t val, bool is_signed) { + int32_t oldval = read_raster_reg(reg, siz, is_signed); + + mod->kernel_cmd = reg | RASTER_WRITE_BIT; + mod->kernel_data_in = val; + + mod->kernel_ready = 1; + while (!mod->kernel_finished) + run_clock(); + mod->kernel_ready = 0; + run_clock(); + + int32_t cval = read_raster_reg(reg, siz, is_signed); + my_assert(cval == val, "written value (%x) != read val (%x)\n", val, cval); + + return oldval; +} + +static void write_shim_cmd(unsigned cmd, uint32_t val) { + mod->shim_cmd = cmd; + mod->shim_cmd_data = val; + mod->shim_cmd_active = 1; + + while (!mod->shim_cmd_finished) + run_clock(); + mod->shim_cmd_active = 0; + run_clock(); +} + +static void read_shim_ptr() { + mod->shim_cmd = RAM_SHIM_READ_PTR; + mod->shim_cmd_active = 1; + + while (!mod->shim_cmd_finished) + run_clock(); + mod->shim_cmd_active = 0; + run_clock(); +} + +#define SAMPLES_PER_LINE 16 +#define NUM_OF_LINES 16 +static size_t expected_store_index = 0; + static void init_values() { - mod->arm = 0; - mod->max_samples_in = 512; - mod->max_lines_in = 512; - /* Settle time is 1 μs */ - mod->settle_time_in = 100; - - mod->dx_in = 17; - mod->dy_in = 13; - mod->coord_dac[0] = 0; - mod->coord_dac[1] = 0; - for (int i = 0; i < ADCNUM; i++) mod->adc_data[i] = 0; mod->adc_finished = 0; - mod->adc_used_in = 0; mod->ram_valid = 0; + + my_assert(write_raster_reg(RASTER_MAX_SAMPLES, SAMPLEWID, SAMPLES_PER_LINE, false) == 0, "samples per line was not zero"); + my_assert(write_raster_reg(RASTER_MAX_LINES, SAMPLEWID, NUM_OF_LINES, false) == 0, "max lines was not zero"); + my_assert(write_raster_reg(RASTER_SETTLE_TIME, TIMERWID, 30, false) == 0, "settle time was not zero"); + my_assert(write_raster_reg(RASTER_DX, DAC_DATA_WID, 12, true) == 0, "dx was not zero"); + my_assert(write_raster_reg(RASTER_DY, DAC_DATA_WID, 12, true) == 0, "dy was not zero"); + my_assert(write_raster_reg(RASTER_USED_ADCS, ADCNUM, 0b111101011, false) == 0, "adcnum was not zero"); + expected_store_index = SAMPLES_PER_LINE * NUM_OF_LINES * 7 * 2; + + write_shim_cmd(RAM_SHIM_WRITE_LOC, 0x10000); + write_shim_cmd(RAM_SHIM_WRITE_LEN, 0x0FFFF); } -uint32_t *measured_values[ADCNUM]; - -static void init_measurements() { - std::default_random_engine generator{}; - std::normal_distribution<> dist{10000, 100}; - std::random_device rd; - - for (int i = 0; i < ADCNUM; i++) { - generator.seed(rd()); - measured_values[i] = new int32_t[mod->max_lines_in][mod->max_samples_in]; - for (int j = 0; j < mod->max_lines_in; j++) { - for (int k = 0; k < mod->max_samples_in; k++) { - measured_values[i][j][k] = dist(generator); - } - } - } -} - -static void deinit_measurement() { - for (int i = 0; i < ADCNUM; i++) { - delete measured_values[i]; - } -} - -static std::array fifo; -static uint32_t read_pos, write_pos; +// Forward and reverse, so multiply by 2 +static std::array stored_values; +static size_t store_index = 0; +static std::array received_values; +static size_t pushed_index = 0; static void handle_ram() { + if (mod->ram_write && !mod->ram_valid) { + my_assert(pushed_index < received_values.max_size(), "pushed_index (%zu) maxed out", pushed_index); + received_values[pushed_index++] = mod->word; + mod->ram_valid = 1; + } else if (!mod->ram_write) { + mod->ram_valid = 0; + } } static void handle_adc() { - static int cntr[ADCNUM] = {0}; - static bool measuring[ADCNUM] = {0}; + uint32_t tmp_adc_arm = mod->adc_arm; + int i = 0; + static int amount_called = 0; - for (int i = 0; i < ADCNUM; i++) { - if (mod->adc_used_in & 1) { + if (mod->adc_arm && mod->adc_arm != mod->adc_finished) { + while (tmp_adc_arm) { + if (tmp_adc_arm & 1) { + my_assert(store_index < stored_values.max_size(), + "%d = %zu", store_index, stored_values.max_size()); + uint32_t x = sign_extend(rand(), 24, false); + memcpy(&stored_values[store_index], &x, sizeof(x)); + mod->adc_data[i] = stored_values[store_index]; + store_index++; + } + + i++; + tmp_adc_arm >>= 1; + } + mod->adc_finished = mod->adc_arm; + fprintf(stderr, "amount called: %d\n", ++amount_called); + } else if (!mod->adc_arm) { + mod->adc_finished = 0; + } } int main(int argc, char **argv) { init(argc, argv); init_values(); - init_measurements(); run_clock(); - mod->arm = 1; - while (!mod->finished) { + write_raster_reg(RASTER_ARM, 1, 1, false); + + while (mod->is_running) { run_clock(); handle_ram(); + handle_adc(); + } + + my_assert(pushed_index % 2 == 0, "uneven pushed index %d", pushed_index); + my_assert(store_index != pushed_index/2, "store_index (%d) != pushed_index/2(%d)\n", store_index, pushed_index/2); + my_assert(store_index == expected_store_index, "store_index (%zu) != (%zu)", store_index, expected_store_index); + exit(0); + + for (size_t i = 0; i < pushed_index; i += 2) { + int32_t calcval = received_values[i+1] << 16 | received_values[i]; + my_assert(calcval == stored_values[i/2], "calcval = %x, stored_values = %x", calcval, stored_values[i/2]); } return 0; diff --git a/firmware/rtl/raster/raster_sim.v b/firmware/rtl/raster/raster_sim.v index 6934e7c..e36478d 100644 --- a/firmware/rtl/raster/raster_sim.v +++ b/firmware/rtl/raster/raster_sim.v @@ -2,23 +2,17 @@ `include "raster_cmds.vh" `include "ram_shim_cmds.vh" module raster_sim #( - parameter SAMPLEWID = 9, - parameter DAC_DATA_WID = 20, - parameter DAC_WID = 24, parameter DAC_WAIT_BETWEEN_CMD = 10, - parameter TIMER_WID = 4, - parameter STEPWID = 16, - parameter ADCNUM = 9, - parameter MAX_ADC_DATA_WID = 24, parameter DAT_WID = 24, parameter RAM_WORD = 16, parameter RAM_WID = 32, - parameter RAM_SIM_WAIT_TIME = 54, + parameter RAM_SIM_WAIT_TIME = 72, parameter ADC_SIM_WAIT_TIME = 54 ) ( input clk, + output is_running, input [`RASTER_CMD_WID-1:0] kernel_cmd, input [`RASTER_DATA_WID-1:0] kernel_data_in, @@ -26,12 +20,12 @@ module raster_sim #( input kernel_ready, output kernel_finished, - output [DAC_DATA_WID-1:0] x_dac, - output [DAC_DATA_WID-1:0] y_dac, + output [`DAC_DATA_WID-1:0] x_dac, + output [`DAC_DATA_WID-1:0] y_dac, - 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, + 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, /* DMA interface */ output [RAM_WORD-1:0] word, @@ -51,13 +45,15 @@ module raster_sim #( * The code to handle each axis (X and Y) are similar. ****/ -reg [DAC_WID-1:0] coord_write_buf [1:0]; -reg [DAC_WID-1:0] coord_to_dac [1:0]; -reg [DAC_WID-1:0] coord_from_dac [1:0]; +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]; wire coord_arm [1:0]; reg coord_finished [1:0]; -reg [DAC_DATA_WID-1:0] coord_dac [1:0]; +reg [`DAC_DATA_WID-1:0] coord_dac [1:0]; assign x_dac = coord_dac[0]; assign y_dac = coord_dac[1]; @@ -75,13 +71,13 @@ generate for (ci = 0; ci < 2; ci = ci + 1) begin coord_to_dac[ci] <= coord_write_buf[ci]; coord_finished[ci] <= 1; - case (coord_from_dac[ci][DAC_WID-1:DAC_WID-4]) + case (coord_from_dac[ci][`DAC_WID-1:`DAC_DATA_WID]) 4'b1001: begin coord_write_buf[ci] <= {4'b1001, coord_dac[ci]}; end 4'b0001: begin coord_write_buf[ci] <= 0; - coord_dac[ci] <= coord_from_dac[ci][DAC_WID-4-1:0]; + coord_dac[ci] <= coord_from_dac[ci][`DAC_DATA_WID-1:0]; end default: ; endcase @@ -98,7 +94,7 @@ end endgenerate * simulator so the C++ code doesn't have to implement timers manually. ****/ -wire [ADCNUM-1:0] adc_arm_internal; +wire [`ADCNUM-1:0] adc_arm_internal; reg [31:0] adc_wait_cntr = 0; always @ (posedge clk) begin @@ -110,6 +106,7 @@ always @ (posedge clk) begin end end else begin adc_wait_cntr <= 0; + adc_arm <= 0; end end @@ -121,6 +118,7 @@ reg [31:0] ram_wait_cntr = 0; always @ (posedge clk) begin if (!ram_write_internal) begin ram_wait_cntr <= 0; + ram_write <= 0; end else if (ram_wait_cntr < RAM_SIM_WAIT_TIME) begin ram_wait_cntr <= ram_wait_cntr + 1; end else begin @@ -128,7 +126,7 @@ always @ (posedge clk) begin end end -wire [MAX_ADC_DATA_WID-1:0] ram_data; +wire [`MAX_ADC_DATA_WID-1:0] ram_data; wire ram_commit; wire ram_finished; @@ -155,23 +153,18 @@ ram_shim #( ); /* Converting array to vector, arrays are easier to handle in Verilator. */ -wire [ADCNUM*MAX_ADC_DATA_WID-1:0] adc_data_internal; +wire [`ADCNUM*`MAX_ADC_DATA_WID-1:0] adc_data_internal; genvar ii; -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] +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 raster #( - .SAMPLEWID(SAMPLEWID), - .DAC_DATA_WID(DAC_DATA_WID), - .DAC_WID(DAC_WID), - .DAC_WAIT_BETWEEN_CMD(DAC_WAIT_BETWEEN_CMD), - .TIMER_WID(TIMER_WID), - .STEPWID(STEPWID), - .MAX_ADC_DATA_WID(MAX_ADC_DATA_WID) + .DAC_WAIT_BETWEEN_CMD(DAC_WAIT_BETWEEN_CMD) ) raster ( .clk(clk), + .is_running(is_running), .kernel_cmd(kernel_cmd), .kernel_data_in(kernel_data_in), @@ -198,5 +191,10 @@ raster #( .mem_finished(ram_finished) ); +initial begin + $dumpfile("raster.fst"); + $dumpvars; +end + endmodule `undefineall