simulate waveform.v
This commit is contained in:
parent
0b6e740af4
commit
4142a0a1b4
|
@ -32,9 +32,10 @@ template <class TOP> class TB {
|
||||||
Verilated::timeInc(1);
|
Verilated::timeInc(1);
|
||||||
tick_count++;
|
tick_count++;
|
||||||
|
|
||||||
if (bailout > 0 && tick_count >= bailout)
|
if (bailout > 0 && tick_count >= bailout) {
|
||||||
exit(1);
|
exit(1);
|
||||||
if (Verilated::gotError())
|
} if (Verilated::gotError()) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
.PHONY: test clean
|
.PHONY: test clean
|
||||||
|
|
||||||
test: obj_dir/Vbram_interface_sim
|
test: obj_dir/Vbram_interface_sim obj_dir/Vwaveform_sim
|
||||||
|
|
||||||
bram_SRC= bram_interface_sim.v dma_sim.v bram_interface.v bram_interface_sim.cpp
|
bram_SRC= bram_interface_sim.v dma_sim.v bram_interface.v bram_interface_sim.cpp
|
||||||
|
|
||||||
|
@ -15,5 +15,15 @@ obj_dir/Vbram_interface_sim: obj_dir/Vbram_interface_sim.mk
|
||||||
cd obj_dir && make -f Vbram_interface_sim.mk
|
cd obj_dir && make -f Vbram_interface_sim.mk
|
||||||
./obj_dir/Vbram_interface_sim
|
./obj_dir/Vbram_interface_sim
|
||||||
|
|
||||||
|
waveform_src = waveform_sim.v waveform.v bram_interface.v dma_sim.v waveform_sim.cpp ../spi/spi_slave_no_write.v
|
||||||
|
obj_dir/Vwaveform_sim.mk: $(waveform_src)
|
||||||
|
verilator --cc --exe -Wall --trace --trace-fst -I../spi \
|
||||||
|
-CFLAGS -DWORD_AMNT=2048 \
|
||||||
|
-CFLAGS -DRAM_WID=32 \
|
||||||
|
$(waveform_src)
|
||||||
|
obj_dir/Vwaveform_sim: obj_dir/Vwaveform_sim.mk $(waveform_src)
|
||||||
|
cd obj_dir && make -f Vwaveform_sim.mk
|
||||||
|
./obj_dir/Vwaveform_sim
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf obj_dir/
|
rm -rf obj_dir/
|
||||||
|
|
|
@ -106,3 +106,4 @@ end else if (!word_next && word_ok) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
`undefineall
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
module bram_interface_sim #(
|
module bram_interface_sim #(
|
||||||
parameter WORD_WID = 24,
|
parameter WORD_WID = 20,
|
||||||
parameter WORD_AMNT_WID = 11,
|
parameter WORD_AMNT_WID = 11,
|
||||||
parameter [WORD_AMNT_WID-1:0] WORD_AMNT = 2047,
|
parameter [WORD_AMNT_WID-1:0] WORD_AMNT = 2047,
|
||||||
parameter RAM_WID = 32,
|
parameter RAM_WID = 32,
|
||||||
|
|
|
@ -42,3 +42,4 @@ always @ (posedge clk) begin
|
||||||
end
|
end
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
`undefineall
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
/* Write a waveform to a DAC. */
|
/* Write a waveform to a DAC. */
|
||||||
|
/* TODO: Add reset pin. */
|
||||||
module waveform #(
|
module waveform #(
|
||||||
parameter DAC_WID = 24,
|
parameter DAC_WID = 24,
|
||||||
parameter DAC_WID_SIZ = 5,
|
parameter DAC_WID_SIZ = 5,
|
||||||
|
@ -18,6 +19,8 @@ module waveform #(
|
||||||
) (
|
) (
|
||||||
input clk,
|
input clk,
|
||||||
input arm,
|
input arm,
|
||||||
|
input halt_on_finish,
|
||||||
|
output reg finished,
|
||||||
input [TIMER_WID-1:0] time_to_wait,
|
input [TIMER_WID-1:0] time_to_wait,
|
||||||
|
|
||||||
/* User interface */
|
/* User interface */
|
||||||
|
@ -100,11 +103,14 @@ reg [1:0] state = WAIT_ON_ARM;
|
||||||
reg [TIMER_WID-1:0] wait_timer = 0;
|
reg [TIMER_WID-1:0] wait_timer = 0;
|
||||||
|
|
||||||
always @ (posedge clk) case (state)
|
always @ (posedge clk) case (state)
|
||||||
WAIT_ON_ARM: if (arm) begin
|
WAIT_ON_ARM: begin
|
||||||
|
finished <= 0;
|
||||||
|
if (arm) begin
|
||||||
state <= DO_WAIT;
|
state <= DO_WAIT;
|
||||||
wait_timer <= time_to_wait;
|
wait_timer <= time_to_wait;
|
||||||
end else begin
|
end else begin
|
||||||
word_rst <= 1;
|
word_rst <= 1;
|
||||||
|
end
|
||||||
end
|
end
|
||||||
DO_WAIT: if (!arm) begin
|
DO_WAIT: if (!arm) begin
|
||||||
state <= WAIT_ON_ARM;
|
state <= WAIT_ON_ARM;
|
||||||
|
@ -126,11 +132,26 @@ WAIT_ON_DAC: if (dac_finished) begin
|
||||||
dac_arm <= 0;
|
dac_arm <= 0;
|
||||||
/* Was the last word read *the* last word? */
|
/* Was the last word read *the* last word? */
|
||||||
if (word_last) begin
|
if (word_last) begin
|
||||||
|
if (!halt_on_finish) begin
|
||||||
state <= WAIT_ON_ARM;
|
state <= WAIT_ON_ARM;
|
||||||
|
finished <= 0;
|
||||||
|
end else begin
|
||||||
|
finished <= 1;
|
||||||
|
end
|
||||||
end else begin
|
end else begin
|
||||||
state <= DO_WAIT;
|
state <= DO_WAIT;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
endcase
|
endcase
|
||||||
|
|
||||||
|
/* Warning! This will crash verilator with a segmentation fault!
|
||||||
|
`ifdef VERILATOR
|
||||||
|
initial begin
|
||||||
|
$dumpfile("waveform.fst");
|
||||||
|
$dumpvars();
|
||||||
|
end
|
||||||
|
`endif
|
||||||
|
*/
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
`undefineall
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include <vector>
|
||||||
|
#include "Vwaveform_sim.h"
|
||||||
|
#include "../testbench.hpp"
|
||||||
|
|
||||||
|
class WaveformTestbench : public TB<Vwaveform_sim> {
|
||||||
|
private:
|
||||||
|
void refresh_posedge();
|
||||||
|
void spi_posedge();
|
||||||
|
public:
|
||||||
|
std::array<uint32_t, WORD_AMNT> ram_refresh_data;
|
||||||
|
int cur_ind;
|
||||||
|
void posedge() override;
|
||||||
|
void refresh_data();
|
||||||
|
WaveformTestbench(int _bailout = 0) : TB<Vwaveform_sim>(_bailout)
|
||||||
|
, ram_refresh_data{}
|
||||||
|
, cur_ind{0} {}
|
||||||
|
};
|
||||||
|
|
||||||
|
void WaveformTestbench::refresh_data() {
|
||||||
|
for (size_t i = 0; i < WORD_AMNT; i++) {
|
||||||
|
uint32_t val = mask_extend(rand(), 20);
|
||||||
|
ram_refresh_data[i] = val;
|
||||||
|
mod.backing_store[i*2] = val & 0xFFFF;
|
||||||
|
mod.backing_store[i*2+1] = val >> 16;
|
||||||
|
}
|
||||||
|
|
||||||
|
mod.refresh_start = 1;
|
||||||
|
mod.start_addr = 0x12340;
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveformTestbench::refresh_posedge() {
|
||||||
|
if (mod.refresh_finished) {
|
||||||
|
mod.refresh_start = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveformTestbench::spi_posedge() {
|
||||||
|
if (mod.finished) {
|
||||||
|
mod.rdy = 0;
|
||||||
|
// Check for proper DAC register.
|
||||||
|
my_assert(mod.from_master >> 20 == 0x1, "%d", mod.from_master >> 20);
|
||||||
|
uint32_t val = mask_extend(mod.from_master & 0xFFFFF, 20);
|
||||||
|
my_assert(val == ram_refresh_data[cur_ind], "(%d) %X != %X",
|
||||||
|
cur_ind, val, ram_refresh_data[cur_ind]);
|
||||||
|
cur_ind++;
|
||||||
|
if (cur_ind == WORD_AMNT)
|
||||||
|
cur_ind = 0;
|
||||||
|
} else if (!mod.finished && !mod.rdy) {
|
||||||
|
mod.rdy = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WaveformTestbench::posedge() {
|
||||||
|
refresh_posedge();
|
||||||
|
spi_posedge();
|
||||||
|
}
|
||||||
|
|
||||||
|
WaveformTestbench *tb;
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int j = 0;
|
||||||
|
Verilated::commandArgs(argc, argv);
|
||||||
|
// Verilated::traceEverOn(true);
|
||||||
|
Verilated::fatalOnError(false);
|
||||||
|
|
||||||
|
tb = new WaveformTestbench();
|
||||||
|
tb->mod.rdy = 1;
|
||||||
|
tb->refresh_data();
|
||||||
|
tb->mod.time_to_wait = 10;
|
||||||
|
tb->mod.arm = 1;
|
||||||
|
|
||||||
|
do {
|
||||||
|
tb->run_clock();
|
||||||
|
} while (!tb->mod.refresh_finished);
|
||||||
|
|
||||||
|
tb->mod.halt_on_finish = 1;
|
||||||
|
do {
|
||||||
|
tb->run_clock();
|
||||||
|
} while (!tb->mod.waveform_finished);
|
||||||
|
|
||||||
|
tb->mod.halt_on_finish = 0;
|
||||||
|
tb->run_clock();
|
||||||
|
tb->mod.halt_on_finish = 1;
|
||||||
|
do {
|
||||||
|
tb->run_clock();
|
||||||
|
} while (!tb->mod.waveform_finished);
|
||||||
|
|
||||||
|
delete tb;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,122 @@
|
||||||
|
module waveform_sim #(
|
||||||
|
parameter DAC_WID = 24,
|
||||||
|
parameter DAC_WID_SIZ = 5,
|
||||||
|
parameter DAC_POLARITY = 0,
|
||||||
|
parameter DAC_PHASE = 1,
|
||||||
|
parameter DAC_CYCLE_HALF_WAIT = 10,
|
||||||
|
parameter DAC_CYCLE_HALF_WAIT_SIZ = 4,
|
||||||
|
parameter DAC_SS_WAIT = 5,
|
||||||
|
parameter DAC_SS_WAIT_SIZ = 3,
|
||||||
|
parameter TIMER_WID = 32,
|
||||||
|
parameter WORD_WID = 20,
|
||||||
|
parameter WORD_AMNT_WID = 11,
|
||||||
|
parameter [WORD_AMNT_WID-1:0] WORD_AMNT = 2047,
|
||||||
|
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,
|
||||||
|
parameter RAM_WID = 32,
|
||||||
|
parameter RAM_WORD_WID = 16,
|
||||||
|
parameter RAM_WORD_INCR = 2
|
||||||
|
) (
|
||||||
|
input clk,
|
||||||
|
input arm,
|
||||||
|
input halt_on_finish,
|
||||||
|
output waveform_finished,
|
||||||
|
input [TIMER_WID-1:0] time_to_wait,
|
||||||
|
|
||||||
|
/* User interface */
|
||||||
|
input refresh_start,
|
||||||
|
input [RAM_WID-1:0] start_addr,
|
||||||
|
output reg refresh_finished,
|
||||||
|
|
||||||
|
output [DAC_WID-1:0] from_master,
|
||||||
|
output finished,
|
||||||
|
input rdy,
|
||||||
|
output spi_err,
|
||||||
|
|
||||||
|
input[RAM_WORD_WID-1:0] backing_store [TOTAL_RAM_WORD_MINUS_ONE:0]
|
||||||
|
);
|
||||||
|
|
||||||
|
wire sck;
|
||||||
|
wire ss_L;
|
||||||
|
wire mosi;
|
||||||
|
|
||||||
|
spi_slave_no_write #(
|
||||||
|
.WID(DAC_WID),
|
||||||
|
.WID_LEN(DAC_WID_SIZ),
|
||||||
|
.POLARITY(DAC_POLARITY),
|
||||||
|
.PHASE(DAC_PHASE)
|
||||||
|
) slave (
|
||||||
|
.clk(clk),
|
||||||
|
.sck(sck),
|
||||||
|
.ss_L(ss_L),
|
||||||
|
.mosi(mosi),
|
||||||
|
.from_master(from_master),
|
||||||
|
.finished(finished),
|
||||||
|
.rdy(rdy),
|
||||||
|
.err(spi_err)
|
||||||
|
);
|
||||||
|
|
||||||
|
wire [RAM_WID-1:0] ram_dma_addr;
|
||||||
|
wire [RAM_WORD_WID-1:0] ram_word;
|
||||||
|
wire ram_read;
|
||||||
|
wire ram_valid;
|
||||||
|
|
||||||
|
dma_sim #(
|
||||||
|
.RAM_WID(RAM_WID),
|
||||||
|
.RAM_WORD_WID(RAM_WORD_WID),
|
||||||
|
.RAM_REAL_START(RAM_REAL_START),
|
||||||
|
.RAM_CNTR_LEN(RAM_CNTR_LEN),
|
||||||
|
.TOTAL_RAM_WORD_MINUS_ONE(TOTAL_RAM_WORD_MINUS_ONE),
|
||||||
|
.DELAY_CNTR_LEN(DELAY_CNTR_LEN),
|
||||||
|
.DELAY_TOTAL(DELAY_TOTAL)
|
||||||
|
) dma_sim (
|
||||||
|
.clk(clk),
|
||||||
|
.ram_dma_addr(ram_dma_addr),
|
||||||
|
.ram_word(ram_word),
|
||||||
|
.ram_read(ram_read),
|
||||||
|
.ram_valid(ram_valid),
|
||||||
|
.backing_store(backing_store)
|
||||||
|
);
|
||||||
|
|
||||||
|
waveform #(
|
||||||
|
.DAC_WID(DAC_WID),
|
||||||
|
.DAC_WID_SIZ(DAC_WID_SIZ),
|
||||||
|
.DAC_POLARITY(DAC_POLARITY),
|
||||||
|
.DAC_PHASE(DAC_PHASE),
|
||||||
|
.DAC_CYCLE_HALF_WAIT(DAC_CYCLE_HALF_WAIT),
|
||||||
|
.DAC_CYCLE_HALF_WAIT_SIZ(DAC_CYCLE_HALF_WAIT_SIZ),
|
||||||
|
.DAC_SS_WAIT(DAC_SS_WAIT),
|
||||||
|
.DAC_SS_WAIT_SIZ(DAC_SS_WAIT_SIZ),
|
||||||
|
.TIMER_WID(TIMER_WID),
|
||||||
|
.WORD_WID(WORD_WID),
|
||||||
|
.WORD_AMNT_WID(WORD_AMNT_WID),
|
||||||
|
.WORD_AMNT(WORD_AMNT),
|
||||||
|
.RAM_WID(RAM_WID),
|
||||||
|
.RAM_WORD_WID(RAM_WORD_WID),
|
||||||
|
.RAM_WORD_INCR(RAM_WORD_INCR)
|
||||||
|
) waveform (
|
||||||
|
.clk(clk),
|
||||||
|
.arm(arm),
|
||||||
|
.halt_on_finish(halt_on_finish),
|
||||||
|
.finished(waveform_finished),
|
||||||
|
.time_to_wait(time_to_wait),
|
||||||
|
|
||||||
|
.refresh_start(refresh_start),
|
||||||
|
.start_addr(start_addr),
|
||||||
|
.refresh_finished(refresh_finished),
|
||||||
|
|
||||||
|
.ram_dma_addr(ram_dma_addr),
|
||||||
|
.ram_word(ram_word),
|
||||||
|
.ram_read(ram_read),
|
||||||
|
.ram_valid(ram_valid),
|
||||||
|
|
||||||
|
.mosi(mosi),
|
||||||
|
.sck(sck),
|
||||||
|
.ss_L(ss_L)
|
||||||
|
);
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
`undefineall
|
Loading…
Reference in New Issue