upsilon/firmware/rtl/raster/raster_sim.v

207 lines
4.5 KiB
Verilog

`timescale 10ns/10ns
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 BASE_ADDR = 32'h1000000,
parameter MAX_BYTE_WID = 13,
parameter DAT_WID = 24,
parameter RAM_WORD = 16,
parameter RAM_WID = 32,
parameter RAM_SIM_WAIT_TIME = 54,
parameter ADC_SIM_WAIT_TIME = 54
) (
input clk,
input arm,
output reg finished,
output reg running,
/* Amount of samples in one line (forward) */
input [SAMPLEWID-1:0] max_samples_in,
/* Amount of lines in the output. */
input [SAMPLEWID-1:0] max_lines_in,
/* Wait time after each step. */
input [TIMER_WID-1:0] settle_time_in,
/* Each step goes (x,y) -> (x + dx, y + dy) forward for each line of
* the output. */
input signed [DAC_DATA_WID-1:0] dx_in,
input signed [DAC_DATA_WID-1:0] dy_in,
/* Vertical steps to go to the next line. */
input signed [DAC_DATA_WID-1:0] dx_vert_in,
input signed [DAC_DATA_WID-1:0] dy_vert_in,
output reg [DAC_DATA_WID-1:0] coord_dac [1:0],
/* 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,
input [MAX_ADC_DATA_WID-1:0] adc_data [ADCNUM-1:0],
input [ADCNUM-1:0] adc_finished,
/* Bitmap for which ADCs are used. */
input [ADCNUM-1:0] adc_used_in,
/* DMA interface */
output [RAM_WORD-1:0] word,
output [RAM_WID-1:0] addr,
output reg ram_write,
input ram_valid
);
/**** DAC simulation ****/
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];
wire coord_arm [1:0];
reg coord_finished [1:0];
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;
case (coord_from_dac[ci][DAC_WID-1:DAC_WID-4])
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];
end
endcase
end else if (!coord_arm[ci]) begin
coord_finished[ci] <= 0;
end
end
end endgenerate
/**** ADC Shim ****/
wire adc_arm_internal;
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;
end
end
/**** RAM Shim ****/
/* Check all addresses are valid. */
property address_in_range;
@(posedge clk)
ram_commit |->
BASE_ADDR <= addr && addr < BASE_ADDR + (1 << MAX_BYTE_WID);
endproperty
address_in_range_assert: assert property (address_in_range);
wire signed [DAT_WID-1:0] ram_data;
wire ram_commit;
wire ram_write_finished;
wire ram_write_internal = 0;
reg [31:0] ram_cntr = 0;
always @ (posedge clk) begin
if (ram_commit) begin
if (ram_cntr < RAM_SIM_WAIT_TIME) begin
ram_cntr <= ram_cntr + 1;
end else begin
ram_write <= 1;
end
end else begin
ram_cntr <= 0;
ram_write <= 0;
end
end
ram_shim #(
.BASE_ADDR(BASE_ADDR),
.MAX_BYTE_WID(MAX_BYTE_WID),
.DAT_WID(DAT_WID),
.RAM_WORD(RAM_WORD),
.RAM_WID(RAM_WID)
) ram (
.clk(clk),
.data(ram_data),
.commit(ram_commit),
.finished(ram_write_finished),
.word(word),
.addr(addr),
.write(ram_write_internal),
.valid(ram_valid)
);
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)
) raster (
.clk(clk),
.arm(arm),
.finished(finished),
.running(running),
.steps_per_sample_in(steps_per_sample_in),
.max_samples_in(max_samples_in),
.max_lines_in(max_lines_in),
.settle_time_in(settle_time_in),
.dx_in(dx_in),
.dy_in(dy_in),
.dx_vert_in(dx_vert_in),
.dy_vert_in(dy_vert_in),
.x_arm(x_arm),
.x_to_dac(x_to_dac),
.x_from_dac(x_from_dac),
.x_finished(x_finished),
.y_arm(y_arm),
.y_to_dac(y_to_dac),
.y_from_dac(y_from_dac),
.y_finished(y_finished),
.adc_arm(adc_arm_internal),
.adc_data(adc_data),
.adc_finished(adc_finished),
.adc_used_in(adc_used_in),
.data(ram_data),
.mem_commit(ram_commit),
.mem_finished(ram_write_finished)
);
endmodule