reset pins and test clock

This commit is contained in:
Peter McGoron 2023-05-10 14:35:57 -04:00
parent 540612e305
commit 15b8fcbe7e
20 changed files with 319 additions and 136 deletions

View File

@ -43,6 +43,7 @@ m4_define(m4_dac_wires, ⟨
/* Same thing but for ADCs */
m4_define(m4_adc_wires, ⟨
input [$3-1:0] adc_sel_$2,
output adc_finished_$2,
input adc_arm_$2,
output [$1-1:0] from_adc_$2
@ -86,6 +87,7 @@ m4_define(m4_dac_switch, ⟨
.SS_WAIT_TIMER_LEN(DAC_SS_WAIT_SIZ)
) dac_master_$2 (
.clk(clk),
.rst_L(rst_L),
.mosi(mosi_port_$2[0]),
.miso(miso_port_$2[0]),
.sck_wire(sck_port_$2[0]),
@ -135,6 +137,27 @@ m4_define(m4_dac_switch, ⟨
/* Same thing but for ADCs */
m4_define(m4_adc_switch, ⟨
wire adc_mosi_unused_output_$2;
wire [$3-1:0] adc_mosi_port_$2; /* Unused! */
wire [$3-1:0] adc_sdo_port_$2;
wire [$3-1:0] adc_sck_port_$2;
wire [$3-1:0] adc_conv_L_port_$2;
spi_switch #(
.PORTS($3)
) adc_switch_$2 (
.select(adc_sel_$2),
.mosi(adc_mosi_unused_output_$2),
.miso(adc_sdo[$2]),
.sck(adc_sck[$2]),
.ss_L(adc_conv_L[$2]),
.mosi_ports(adc_mosi_port_$2),
.miso_ports(adc_sdo_port_$2),
.sck_ports(adc_sck_port_$2),
.ss_L_ports(adc_conv_L_port_$2)
);
spi_master_ss_no_write #(
.WID($1),
.WID_LEN(ADC_WID_SIZ),
@ -146,13 +169,21 @@ m4_define(m4_adc_switch, ⟨
.PHASE(ADC_PHASE)
) adc_master_$2 (
.clk(clk),
.miso(adc_sdo[$2]),
.sck_wire(adc_sck[$2]),
.ss_L(adc_conv_L[$2]),
.rst_L(rst_L),
.miso(adc_sdo_port_$2[0]),
.sck_wire(adc_sck_port_$2[0]),
.ss_L(adc_conv_L_port_$2[0]),
.finished(adc_finished_$2),
.arm(adc_arm_$2),
.from_slave(from_adc_$2)
)
);
/* 2nd option for each ADC is the non-converting option.
* This is used to flush output from reset ADCs.
*/
assign adc_sdo_port[1] = adc_sdo_port[0];
assign adc_sck_port[1] = adc_sck_port[0];
assign adc_conv_L_port[1] = 1;
⟩)
/*********************************************************/
@ -181,7 +212,7 @@ m4_define(DAC_PORTS_CONTROL_LOOP, (DAC_PORTS + 1))
parameter WF_RAM_WORD_WID = 16,
parameter WF_RAM_WORD_INCR = 2,
parameter ADC_PORTS = 1,
parameter ADC_PORTS = 2,
m4_define(ADC_PORTS_CONTROL_LOOP, (ADC_PORTS + 1))
parameter ADC_NUM = 8,
/* Three types of ADC. For now assume that their electronics
@ -211,6 +242,7 @@ m4_define(CL_DATA_WID, CL_CONSTS_WID)
parameter CL_CYCLE_COUNT_WID = 18
) (
input clk,
input rst_L,
output [DAC_NUM-1:0] dac_mosi,
input [DAC_NUM-1:0] dac_miso,
@ -230,16 +262,14 @@ m4_define(CL_DATA_WID, CL_CONSTS_WID)
m4_dac_wires(DAC_PORTS, 6),
m4_dac_wires(DAC_PORTS, 7),
input [ADC_PORTS_CONTROL_LOOP-1:0] adc_sel_0,
m4_adc_wires(ADC_TYPE1_WID, 0),
m4_adc_wires(ADC_TYPE1_WID, 1),
m4_adc_wires(ADC_TYPE1_WID, 2),
m4_adc_wires(ADC_TYPE1_WID, 3),
m4_adc_wires(ADC_TYPE1_WID, 4),
m4_adc_wires(ADC_TYPE1_WID, 5),
m4_adc_wires(ADC_TYPE1_WID, 6),
m4_adc_wires(ADC_TYPE1_WID, 7),
m4_adc_wires(ADC_TYPE1_WID, 0, ADC_PORTS_CONTROL_LOOP),
m4_adc_wires(ADC_TYPE1_WID, 1, ADC_PORTS),
m4_adc_wires(ADC_TYPE1_WID, 2, ADC_PORTS),
m4_adc_wires(ADC_TYPE1_WID, 3, ADC_PORTS),
m4_adc_wires(ADC_TYPE1_WID, 4, ADC_PORTS),
m4_adc_wires(ADC_TYPE1_WID, 5, ADC_PORTS),
m4_adc_wires(ADC_TYPE1_WID, 6, ADC_PORTS),
m4_adc_wires(ADC_TYPE1_WID, 7, ADC_PORTS),
output cl_in_loop,
input [M4_CONTROL_LOOP_CMD_WIDTH-1:0] cl_cmd,
@ -263,58 +293,53 @@ m4_dac_switch(DAC_PORTS, 5);
m4_dac_switch(DAC_PORTS, 6);
m4_dac_switch(DAC_PORTS, 7);
reg [ADC_CYCLE_HALF_WAIT_SIZ-1:0] counter = 0;
initial test_clock <= 0;
reg [8-1:0] counter = 0;
/*
always @ (posedge clk) begin
if (counter >= ADC_CYCLE_HALF_WAIT) begin
if (!rst_L) begin
counter <= 0;
test_clock <= 0;
end else if (counter >= ADC_CYCLE_HALF_WAIT) begin
counter <= 0;
test_clock <= !test_clock;
end else begin
counter <= counter + 1;
end
end
*/
/*
always @ (posedge clk) begin
if(!rst_L) begin
test_clock <= 0;
end else begin
test_clock <= !test_clock;
end
end
*/
always @ (posedge clk) begin
if (!rst_L) begin
counter <= 0;
test_clock <= 0;
end else begin
if (counter >= 3) begin
counter <= 0;
test_clock <= !test_clock;
end else begin
counter <= counter + 1;
end
end
end
/* 1st adc is Type 1 (18 bit) */
wire [ADC_PORTS_CONTROL_LOOP-1:0] adc_conv_L_port_0;
wire [ADC_PORTS_CONTROL_LOOP-1:0] adc_sdo_port_0;
wire [ADC_PORTS_CONTROL_LOOP-1:0] adc_sck_port_0;
wire [ADC_PORTS_CONTROL_LOOP-1:0] adc_mosi_port_0_unassigned;
wire adc_mosi_unassigned;
spi_switch #(
.PORTS(ADC_PORTS_CONTROL_LOOP)
) switch_adc_0 (
.select(adc_sel_0),
.mosi(adc_mosi_unassigned),
.miso(adc_sdo[0]),
.sck(adc_sck[0]),
.ss_L(adc_conv_L[0]),
.mosi_ports(adc_mosi_port_0_unassigned),
.miso_ports(adc_sdo_port_0),
.sck_ports(adc_sck_port_0),
.ss_L_ports(adc_conv_L_port_0)
);
spi_master_ss_no_write #(
.WID(ADC_TYPE1_WID),
.WID_LEN(ADC_WID_SIZ),
.CYCLE_HALF_WAIT(ADC_CYCLE_HALF_WAIT),
.TIMER_LEN(ADC_CYCLE_HALF_WAIT_SIZ),
.SS_WAIT(ADC_CONV_WAIT),
.SS_WAIT_TIMER_LEN(ADC_CONV_WAIT_SIZ),
.POLARITY(ADC_POLARITY),
.PHASE(ADC_PHASE)
) adc_master_0 (
.clk(clk),
.miso(adc_sdo_port_0[0]),
.sck_wire(adc_sck_port_0[0]),
.ss_L(adc_conv_L_port_0[0]),
.finished(adc_finished_0),
.arm(adc_arm_0),
.from_slave(from_adc_0)
);
m4_adc_switch(ADC_TYPE1_WID, 0, ADC_PORTS_CONTROL_LOOP);
m4_adc_switch(ADC_TYPE1_WID, 1, ADC_PORTS);
m4_adc_switch(ADC_TYPE1_WID, 2, ADC_PORTS);
m4_adc_switch(ADC_TYPE1_WID, 3, ADC_PORTS);
m4_adc_switch(ADC_TYPE1_WID, 4, ADC_PORTS);
m4_adc_switch(ADC_TYPE1_WID, 5, ADC_PORTS);
m4_adc_switch(ADC_TYPE1_WID, 6, ADC_PORTS);
m4_adc_switch(ADC_TYPE1_WID, 7, ADC_PORTS);
control_loop #(
.ADC_WID(ADC_TYPE1_WID),
@ -342,14 +367,15 @@ control_loop #(
.DAC_SS_WAIT_SIZ(DAC_SS_WAIT_SIZ)
) cl (
.clk(clk),
.rst_L(rst_L),
.in_loop(cl_in_loop),
.dac_mosi(mosi_port_0[2]),
.dac_miso(miso_port_0[2]),
.dac_ss_L(ss_L_port_0[2]),
.dac_sck(sck_port_0[2]),
.adc_miso(adc_sdo_port_0[1]),
.adc_conv_L(adc_conv_L_port_0[1]),
.adc_sck(adc_sck_port_0[1]),
.adc_miso(adc_sdo_port_0[2]),
.adc_conv_L(adc_conv_L_port_0[2]),
.adc_sck(adc_sck_port_0[2]),
.cmd(cl_cmd),
.word_in(cl_word_in),
.word_out(cl_word_out),
@ -357,12 +383,4 @@ control_loop #(
.finish_cmd(cl_finish_cmd)
);
m4_adc_switch(ADC_TYPE1_WID, 1);
m4_adc_switch(ADC_TYPE1_WID, 2);
m4_adc_switch(ADC_TYPE1_WID, 3);
m4_adc_switch(ADC_TYPE1_WID, 4);
m4_adc_switch(ADC_TYPE1_WID, 5);
m4_adc_switch(ADC_TYPE1_WID, 6);
m4_adc_switch(ADC_TYPE1_WID, 7);
endmodule

View File

@ -1,7 +1,7 @@
# Generate verilog from m4 file
%.v: %.v.m4
#m4 -P --synclines $< | awk -v filename=$< '/^#line/ {printf("`line %d %s 0\n", $$2, filename); next} {print}' > $@
# NOTE: f4pga yosys does not support `line directives. Use above for debug.
%.v: %.v.m4
m4 -P $< > $@
%_preprocessed.v: %.v
verilator -P -E $< > $@

View File

@ -7,6 +7,7 @@ module adc_sim #(
input clk,
input [WID-1:0] indat,
input rst_L,
output reg request,
input fulfilled,
output err,
@ -26,7 +27,14 @@ reg rdy = 0;
wire spi_fin;
always @ (posedge clk) begin
if (ss && !ss_raised) begin
if (!rst_L) begin
ss_raised <= 0;
fulfilled_raised <= 0;
ss_buf_L <= 1;
data <= 0;
rdy <= 0;
request <= 0;
end else if (ss && !ss_raised) begin
request <= 1;
ss_raised <= 1;
end else if (ss_raised && !ss) begin
@ -56,6 +64,7 @@ spi_slave_no_read #(
) spi (
.clk(clk),
.sck(sck),
.rst_L(rst_L),
.ss_L(ss_buf_L),
.miso(miso),
.to_master(data),

View File

@ -41,6 +41,7 @@ m4_define(M4_E_WID, (DAC_DATA_WID + 1))
parameter DAC_SS_WAIT_SIZ = 3
) (
input clk,
input rst_L,
output in_loop,
output dac_mosi,
@ -64,6 +65,7 @@ m4_define(M4_E_WID, (DAC_DATA_WID + 1))
reg dac_arm;
reg dac_finished;
wire dac_ready_to_arm_unused;
reg [DAC_WID-1:0] to_dac;
/* verilator lint_off UNUSED */
@ -80,6 +82,8 @@ spi_master_ss #(
.SS_WAIT_TIMER_LEN(DAC_SS_WAIT_SIZ)
) dac_master (
.clk(clk),
.rst_L(rst_L),
.ready_to_arm(dac_ready_to_arm_unused),
.mosi(dac_mosi),
.miso(dac_miso),
.sck_wire(dac_sck),
@ -93,6 +97,7 @@ spi_master_ss #(
reg adc_arm;
reg adc_finished;
wire [ADC_WID-1:0] measured_value;
wire adc_ready_to_arm_unused;
localparam [3-1:0] DAC_REGISTER = 3'b001;
@ -107,6 +112,8 @@ spi_master_ss_no_write #(
.SS_WAIT_TIMER_LEN(ADC_CONV_WAIT_SIZ)
) adc_master (
.clk(clk),
.ready_to_arm(adc_ready_to_arm_unused),
.rst_L(rst_L),
.arm(adc_arm),
.from_slave(measured_value),
.miso(adc_miso),
@ -166,6 +173,7 @@ control_loop_math #(
.ADC_TO_DAC({32'b01000001100, 32'b01001001101110100101111000110101})
) math (
.clk(clk),
.rst_L(rst_L),
.arm(arm_math),
.finished(math_finished),
.setpt(setpt),
@ -228,7 +236,10 @@ reg [DELAY_WID-1:0] timer = 0;
/**** Timing. ****/
always @ (posedge clk) begin
if (state == CYCLE_START && timer == 0) begin
if (!rst_L) begin
counting_timer <= 0;
last_timer <= 0;
end else if (state == CYCLE_START && timer == 0) begin
counting_timer <= 1;
last_timer <= counting_timer;
end else if (running) begin
@ -245,7 +256,11 @@ wire write_control = state == CYCLE_START || !running;
reg dirty_bit = 0;
always @ (posedge clk) begin
if (start_cmd && !finish_cmd) begin
if (!rst_L) begin
dirty_bit <= 0;
finish_cmd <= 0;
word_out <= 0;
end else if (start_cmd && !finish_cmd) begin
case (cmd)
M4_CONTROL_LOOP_NOOP:
finish_cmd <= 1;
@ -331,7 +346,21 @@ end
assign in_loop = state != INIT_READ_FROM_DAC || running;
always @ (posedge clk) begin
case (state)
if (!rst_L) begin
to_dac <= 0;
dac_arm <= 0;
state <= INIT_READ_FROM_DAC;
timer <= 0;
stored_dac_val <= 0;
setpt <= 0;
dely <= 0;
cl_I_reg <= 0;
adjval_prev <= 0;
err_prev <= 0;
adc_arm <= 0;
arm_math <= 0;
end else case (state)
INIT_READ_FROM_DAC: begin
if (running) begin
to_dac <= {1'b1, DAC_REGISTER, 20'b0};

View File

@ -42,6 +42,7 @@ m4_define(M4_E_WID, (DAC_WID + 1))
) (
input clk,
input arm,
input rst_L,
output reg finished,
input signed [ADC_WID-1:0] setpt,
@ -86,6 +87,7 @@ boothmul #(
.a1(a1),
.a2(a2),
.clk(clk),
.rst_L(rst_L),
.outn(out_untrunc),
.fin(mul_fin),
.arm(mul_arm)
@ -175,7 +177,23 @@ wire signed [M4_CONSTS_WID-1:0] tmpstore_view = tmpstore[M4_CONSTS_WID-1:0];
always @ (posedge clk) begin
case (state)
if (!rst_L) begin
state <= WAIT_ON_ARM;
a1 <= 0;
finished <= 0;
mul_arm <= 0;
a2 <= 0;
e_cur <= 0;
`ifdef DEBUG_CONTROL_LOOP_MATH
dt_reg <= 0;
idt_reg <= 0;
epidt_reg <= 0;
ep_reg <= 0;
`endif
add_sat <= 0;
adj_val <= 0;
tmpstore <= 0;
end else case (state)
WAIT_ON_ARM:
if (arm) begin
a1[CONSTS_FRAC-1:0] <= 0;

View File

@ -67,6 +67,7 @@ static void calculate() {
int main(int argc, char **argv) {
init(argc, argv);
mod->arm = 0;
mod->rst_L = 1;
run_clock();
Transfer func = Transfer{150, 0, 2, 1.1, 10, -1};

View File

@ -19,6 +19,7 @@ module control_loop_sim_top #(
parameter DELAY_WID = 16
)(
input clk,
input rst_L,
output in_loop,
output [DAC_DATA_WID-1:0] curset,
@ -53,6 +54,7 @@ adc_sim #(
.PHASE(ADC_PHASE)
) adc (
.clk(clk),
.rst_L(rst_L),
.indat(measured_value),
.request(request),
.fulfilled(fulfilled),
@ -77,6 +79,7 @@ dac_sim #(
.PHASE(DAC_PHASE)
) dac (
.clk(clk),
.rst_L(rst_L),
.curset(curset),
.mosi(dac_mosi),
.miso(dac_miso),
@ -105,6 +108,7 @@ control_loop #(
.DAC_PHASE(DAC_PHASE)
) cloop (
.clk(clk),
.rst_L(rst_L),
.in_loop(in_loop),
.dac_mosi(dac_mosi),
.dac_miso(dac_miso),

View File

@ -6,6 +6,7 @@ module dac_sim #(
parameter WID_LEN = 5
) (
input clk,
input rst_L,
output reg [DATA_WID-1:0] curset,
@ -23,7 +24,12 @@ wire spi_fin;
reg [WID-4-1:0] ctrl_register = 0;
always @ (posedge clk) begin
if (spi_fin) begin
if (!rst_L) begin
curset <= 0;
to_master <= 0;
rdy <= 0;
ctrl_register <= 0;
end else if (spi_fin) begin
rdy <= 0;
case (from_master[WID-1:WID-4])
4'b1001: begin
@ -56,6 +62,7 @@ spi_slave #(
.clk(clk),
.sck(sck),
.ss_L(ss_L),
.rst_L(rst_L),
.miso(miso),
.mosi(mosi),
.from_master(from_master),

View File

@ -1,6 +1,7 @@
# Makefile for tests and hardware verification.
.PHONY: test clean codegen
include ../common.makefile
all: test codegen
test: obj_dir/Vspi_switch

View File

@ -1,4 +1,4 @@
/* (c) Peter McGoron 2022 v0.2
/* (c) Peter McGoron 2022 v0.3
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v.2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -30,6 +30,7 @@ spi_master
)
(
input clk,
input rst_L,
`ifndef SPI_MASTER_NO_READ
output reg [WID-1:0] from_slave,
input miso,
@ -40,6 +41,7 @@ spi_master
`endif
output reg sck_wire,
output reg finished,
output reg ready_to_arm,
input arm
);
@ -134,17 +136,39 @@ task cycle_change();
end
endtask
initial ready_to_arm = 1;
always @ (posedge clk) begin
case (state)
if (!rst_L) begin
idle_state();
finished <= 0;
state <= WAIT_ON_ARM;
ready_to_arm <= 1;
`ifndef SPI_MASTER_NO_READ
from_slave <= 0;
`endif
`ifndef SPI_MASTER_NO_WRITE
send_buf <= 0;
`endif
end else case (state)
WAIT_ON_ARM: begin
`ifdef SIMULATION
if (!ready_to_arm)
$error("not ready to arm in wait_on_arm");
`endif
if (!arm) begin
idle_state();
finished <= 0;
end else begin
setup_bits();
ready_to_arm <= 0;
end
end
ON_CYCLE: begin
`ifdef SIMULATION
if (ready_to_arm)
$error("ready_to_arm while on cycle");
`endif
if (sck) begin // rising edge
if (PHASE == 1) begin
write_data();
@ -174,6 +198,10 @@ always @ (posedge clk) begin
end
end
CYCLE_WAIT: begin
`ifdef SIMULATION
if (ready_to_arm)
$error("ready_to_arm while in cycle wait");
`endif
if (timer == CYCLE_HALF_WAIT) begin
timer <= 1;
cycle_change();
@ -182,10 +210,15 @@ always @ (posedge clk) begin
end
end
WAIT_FINISHED: begin
`ifdef SIMULATION
if (ready_to_arm)
$error("ready_to_arm while in wait finished");
`endif
finished <= 1;
idle_state();
if (!arm) begin
state <= WAIT_ON_ARM;
ready_to_arm <= 1;
end
end
endcase

View File

@ -1,3 +1,8 @@
/* (c) Peter McGoron 2022 v0.3
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v.2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
*/
/* spi master with integrated ability to wait a certain amount of cycles
* after activating SS.
*/
@ -17,6 +22,7 @@ module `SPI_MASTER_SS_NAME
)
(
input clk,
input rst_L,
`ifndef SPI_MASTER_NO_READ
output [WID-1:0] from_slave,
input miso,
@ -27,6 +33,7 @@ module `SPI_MASTER_SS_NAME
`endif
output sck_wire,
output finished,
output ready_to_arm,
output ss_L,
input arm
);
@ -44,6 +51,7 @@ assign ss_L = !ss;
.PHASE(PHASE)
) master (
.clk(clk),
.rst_L(rst_L),
`ifndef SPI_MASTER_NO_READ
.from_slave(from_slave),
.miso(miso),
@ -54,6 +62,7 @@ assign ss_L = !ss;
`endif
.sck_wire(sck_wire),
.finished(finished),
.ready_to_arm(ready_to_arm),
.arm(arm_master)
);
@ -70,7 +79,12 @@ task master_arm();
endtask
always @ (posedge clk) begin
case (state)
if (!rst_L) begin
state <= WAIT_ON_ARM;
timer <= 0;
arm_master <= 0;
ss <= 0;
end else case (state)
WAIT_ON_ARM: begin
if (arm) begin
timer <= 1;

View File

@ -1,4 +1,4 @@
/* (c) Peter McGoron 2022 v0.2
/* (c) Peter McGoron 2022 v0.3
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v.2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/.
@ -20,6 +20,7 @@ spi_slave
)
(
input clk,
input rst_L,
input sck,
input ss_L,
`ifndef SPI_SLAVE_NO_READ
@ -96,6 +97,21 @@ task check_counter();
endtask
always @ (posedge clk) begin
if (!rst_L) begin
sck_delay <= 0;
bit_counter <= 0;
ss_delay <= 0;
ready_at_start <= 0;
`ifndef SPI_SLAVE_NO_READ
from_master <= 0;
`endif
`ifndef SPI_SLAVE_NO_WRITE
miso <= 0;
send_buf <= 0;
`endif
finished <= 0;
err <= 0;
end else begin
sck_delay <= sck;
ss_delay <= ss;
@ -138,17 +154,13 @@ always @ (posedge clk) begin
default: ;
endcase
end
2'b00: begin
if (!rdy) begin
2'b00: if (!rdy) begin
finished <= 0;
err <= 0;
end
`ifndef SPI_SLAVE_NO_WRITE
miso <= 0;
`endif
end
endcase
end
end
endmodule
`undefineall

View File

@ -8,6 +8,7 @@ module bram_interface #(
parameter RAM_WORD_INCR = 2
) (
input clk,
input rst_L,
/* autoapproach interface */
output reg [WORD_WID-1:0] word,
@ -35,6 +36,7 @@ initial refresh_finished = 0;
initial ram_dma_addr = 0;
initial ram_read = 0;
/* TODO: how to initialize? */
reg [WORD_WID-1:0] backing_buffer [WORD_AMNT:0];
localparam WAIT_ON_REFRESH = 0;
@ -42,10 +44,20 @@ localparam READ_LOW_WORD = 1;
localparam READ_HIGH_WORD = 2;
localparam WAIT_ON_REFRESH_DEASSERT = 3;
reg [1:0] refresh_state = 0;
reg [1:0] refresh_state = WAIT_ON_REFRESH;
reg [WORD_AMNT_WID-1:0] word_cntr_refresh = 0;
always @ (posedge clk) case (refresh_state)
always @ (posedge clk) if (!rst_L) begin
word <= 0;
word_last <= 0;
word_ok <= 0;
refresh_finished <= 0;
ram_dma_addr <= 0;
ram_read <= 0;
/* Do not reset backing buffer because that would take too long */
refresh_state <= WAIT_ON_REFRESH;
word_cntr_refresh <= 0;
end else case (refresh_state)
WAIT_ON_REFRESH: if (refresh_start) begin
ram_dma_addr <= start_addr;
refresh_state <= READ_LOW_WORD;
@ -84,7 +96,7 @@ endcase
reg [WORD_AMNT_WID-1:0] auto_cntr = 0;
always @ (posedge clk) if (word_rst) begin
always @ (posedge clk) if (word_rst || !rst_L) begin
auto_cntr <= 0;
word_ok <= 0;
word_last <= 0;

View File

@ -88,11 +88,14 @@ int main(int argc, char *argv[]) {
Verilated::fatalOnError(false);
tb = new TB<Vbram_interface_sim>();
tb->mod.rst_L = 1;
printf("test basic read/write\n");
refresh_data();
printf("\ttest 1\n");
test_aa_read_1();
refresh_data();
printf("\ttest 2\n");
test_aa_read_1();
printf("test resetting\n");

View File

@ -12,6 +12,7 @@ module bram_interface_sim #(
parameter RAM_WORD_INCR = 2
) (
input clk,
input rst_L,
/* autoapproach interface */
output [WORD_WID-1:0] word,
@ -59,6 +60,7 @@ bram_interface #(
.RAM_WORD_INCR(RAM_WORD_INCR)
) bram_interface (
.clk(clk),
.rst_L(rst_L),
.word(word),
.word_next(word_next),
.word_last(word_last),

View File

@ -1,6 +1,5 @@
/* Write a waveform to a DAC. */
/* TODO: Add reset pin.
* Add "how many values to go" counter. */
/* TODO: Add "how many values to go" counter. */
module waveform #(
parameter DAC_WID = 24,
parameter DAC_WID_SIZ = 5,
@ -19,6 +18,7 @@ module waveform #(
parameter RAM_WORD_INCR = 2
) (
input clk,
input rst_L,
input arm,
input halt_on_finish,
/* NOTE:
@ -55,10 +55,10 @@ module waveform #(
);
wire [WORD_WID-1:0] word;
reg word_next;
reg word_next = 0;
wire word_ok;
wire word_last;
reg word_rst;
reg word_rst = 1;
bram_interface #(
.WORD_WID(WORD_WID),
@ -69,6 +69,7 @@ bram_interface #(
.RAM_WORD_INCR(RAM_WORD_INCR)
) bram (
.clk(clk),
.rst_L(rst_L),
.word(word),
.word_next(word_next),
.word_last(word_last),
@ -86,8 +87,9 @@ bram_interface #(
);
wire dac_finished;
reg dac_arm;
reg [DAC_WID-1:0] dac_out;
reg dac_arm = 0;
reg [DAC_WID-1:0] dac_out = 0;
wire dac_ready_to_arm_unused;
spi_master_ss_no_read #(
.WID(DAC_WID),
@ -100,6 +102,8 @@ spi_master_ss_no_read #(
.SS_WAIT_TIMER_LEN(DAC_SS_WAIT_SIZ)
) dac_master (
.clk(clk),
.rst_L(rst_L),
.ready_to_arm(dac_ready_to_arm_unused),
.mosi(mosi),
.sck_wire(sck),
.ss_L(ss_L),
@ -119,11 +123,20 @@ reg [TIMER_WID-1:0] wait_timer = 0;
assign running = state != WAIT_ON_ARM;
always @ (posedge clk) case (state)
always @ (posedge clk) if (!rst_L) begin
state <= WAIT_ON_ARM;
wait_timer <= 0;
finished <= 0;
word_rst <= 1;
word_next <= 0;
dac_out <= 0;
dac_arm <= 0;
end else case (state)
WAIT_ON_ARM: begin
finished <= 0;
if (arm) begin
state <= DO_WAIT;
word_rst <= 0;
wait_timer <= time_to_wait;
end else begin
word_rst <= 1;

View File

@ -1,3 +1,4 @@
/* TODO: impleement reset for dma and test both separetely */
#include <vector>
#include "Vwaveform_sim.h"
#include "../testbench.hpp"
@ -65,6 +66,7 @@ int main(int argc, char *argv[]) {
tb = new WaveformTestbench();
tb->mod.rdy = 1;
tb->mod.rst_L = 1;
tb->refresh_data();
tb->mod.time_to_wait = 10;
tb->mod.halt_on_finish = 1;

View File

@ -21,6 +21,7 @@ module waveform_sim #(
parameter RAM_WORD_INCR = 2
) (
input clk,
input rst_L,
input arm,
input halt_on_finish,
output waveform_finished,
@ -52,6 +53,7 @@ spi_slave_no_write #(
) slave (
.clk(clk),
.sck(sck),
.rst_L(rst_L),
.ss_L(ss_L),
.mosi(mosi),
.from_master(from_master),
@ -101,6 +103,7 @@ waveform #(
) waveform (
.clk(clk),
.arm(arm),
.rst_L(rst_L),
.halt_on_finish(halt_on_finish),
.running(running),
.finished(waveform_finished),

View File

@ -26,6 +26,7 @@ io = [
("adc_conv", 0, Pins("V15 T11 N15 U18 U11 R10 R16 U17"), IOStandard("LVCMOS33")),
("adc_sck", 0, Pins("U16 R12 M16 R17 V16 R11 N16 T18"), IOStandard("LVCMOS33")),
("adc_sdo", 0, Pins("P14 T14 V17 P17 M13 R13 N14 R18"), IOStandard("LVCMOS33")),
("module_reset", 0, Pins("D9"), IOStandard("LVCMOS33")),
("test_clock", 0, Pins("P18"), IOStandard("LVCMOS33"))
]
@ -121,6 +122,7 @@ class Base(Module, AutoCSR):
self._make_csr("cl_finish_cmd", CSRStatus, 1, "Control Loop Command Finished Flag")
self.kwargs["i_clk"] = clk
self.kwargs["i_rst_L"] = ~platform.request("module_reset")
self.kwargs["i_dac_miso"] = platform.request("dac_miso")
self.kwargs["o_dac_mosi"] = platform.request("dac_mosi")
self.kwargs["o_dac_sck"] = platform.request("dac_sck")
@ -138,9 +140,8 @@ class Base(Module, AutoCSR):
# Clock and Reset Generator
# I don't know how this works, I only know that it does.
# TODO: Connect cpu_reset pin to Verilog modules.
class _CRG(Module):
def __init__(self, platform, sys_clk_freq, with_dram=True, with_rst=True):
def __init__(self, platform, sys_clk_freq, with_dram, rst_pin):
self.rst = Signal()
self.clock_domains.cd_sys = ClockDomain()
self.clock_domains.cd_eth = ClockDomain()
@ -151,7 +152,7 @@ class _CRG(Module):
# Clk/Rst.
clk100 = platform.request("clk100")
rst = ~platform.request("cpu_reset") if with_rst else 0
rst = ~rst_pin if rst_pin is not None else 0
# PLL.
self.submodules.pll = pll = S7PLL(speedgrade=-1)
@ -174,7 +175,8 @@ class CryoSNOM1SoC(SoCCore):
def __init__(self, variant):
sys_clk_freq = int(100e6)
platform = board_spec.Platform(variant=variant, toolchain="f4pga")
self.submodules.crg = _CRG(platform, sys_clk_freq, True)
rst = platform.request("cpu_reset")
self.submodules.crg = _CRG(platform, sys_clk_freq, True, rst)
# These source files need to be sorted so that modules
# that rely on another module come later. For instance,
# `control_loop` depends on `control_loop_math`, so