From 74d552a323014549f5b81a2f56cfb3d7b6817c1c Mon Sep 17 00:00:00 2001 From: Eric Yu Date: Tue, 16 Jan 2024 10:07:32 -0800 Subject: [PATCH] modify tb --- .../modules/qlaser_dacs_pulse_channel.vhdl | 32 +++----- src/hdl/pkg/qlaser_dacs_pulse_channel_pkg.vhd | 31 ++++++++ src/hdl/tb/tb_cpubus_dacs_pulse_channel.vhdl | 76 ++++++++++++------- tools/sim/run.do | 2 +- tools/sim/vsim_stacktrace.vstf | 12 +++ tools/sim/waves_do/pp_sm_wavetables.do | 54 +++++++++++++ 6 files changed, 160 insertions(+), 47 deletions(-) create mode 100644 src/hdl/pkg/qlaser_dacs_pulse_channel_pkg.vhd create mode 100644 tools/sim/vsim_stacktrace.vstf create mode 100644 tools/sim/waves_do/pp_sm_wavetables.do diff --git a/src/hdl/modules/qlaser_dacs_pulse_channel.vhdl b/src/hdl/modules/qlaser_dacs_pulse_channel.vhdl index a76aa60..c0e27f0 100644 --- a/src/hdl/modules/qlaser_dacs_pulse_channel.vhdl +++ b/src/hdl/modules/qlaser_dacs_pulse_channel.vhdl @@ -7,6 +7,7 @@ use ieee.std_logic_1164.all; use ieee.numeric_std.all; use work.qlaser_pkg.all; +use work.qlaser_dacs_pulse_channel_pkg.all; entity qlaser_dacs_pulse_channel is port ( @@ -39,26 +40,6 @@ end entity; -- Single channel pulse generator with two RAMs --------------------------------------------------------------------------- architecture channel of qlaser_dacs_pulse_channel is --- Constants declearations -constant C_RAM_SELECT : integer := 11; -- Select bit for which RAM for CPU read/write --- constant C_NUM_PULSE : integer := 16; -- Number of output data values from pulse RAM (16x24-bit) - -constant C_START_TIME : integer := 24; -- Start time for pulse generation -constant C_BITS_ADDR_START : integer := 12; -- Number of bits for starting address -constant C_BITS_ADDR_LENGTH : integer := 10; -- Number of bits for length address used by an edge of a pulse -constant C_BITS_GAIN_FACTOR : integer := 16; -- Number of bits in gain table -constant C_BITS_TIME_FACTOR : integer := 16; -- Number of bits in time table -constant C_BITS_TIME_INT : integer := 14; -- Starting bit for time integer part of the time factor, counting from MSB -constant C_BITS_TIME_FRAC : integer := 5; -- Starting bit for time fractional part of the time factor, counting from MSB -constant C_BITS_ADDR_TOP : integer := 17; -- Number of bits for the "flat top", the top of the pulse - -constant C_LENGTH_WAVEFORM : integer := 4096; -- Number of output data values from waveform RAM (4kx16-bit) -constant C_BITS_ADDR_WAVE : integer := 16; -- Number of bits in address for waveform RAM - -constant C_BITS_ADDR_PULSE : integer := 10; -- Number of bits in address for pulse definition RAM -constant C_LEN_PULSE : integer := 2**C_BITS_ADDR_PULSE; -- Numbers of address for pulse definition RAM -constant C_PC_INCR : integer := 4; -- Width of pulse counter increment - -- Signal declarations for pulse RAM signal ram_pulse_we : std_logic_vector( 0 downto 0); -- Write enable for pulse RAM signal ram_pulse_addra : std_logic_vector( 9 downto 0); -- Address for pulse RAM @@ -445,6 +426,7 @@ begin -- reset counters for transitions cnt_wave_len <= (others=>'0'); cnt_wave_top <= (others=>'0'); + -- TODO: toSara: do we need to consider the even of no flat top? else cnt_wave_len <= std_logic_vector(unsigned(cnt_wave_len) + 1); ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) + 1); @@ -509,5 +491,15 @@ begin end case; end if; end process; + + -- AXI-Stream output. + -- TBD: This should come from a FIFO + -- TODO: the bits are not correct, should be top bits (C_BITS_GAIN_FACTOR + 16 downto C_BITS_GAIN_FACTOR), but for now just make it this way so modelsim can simulate + -- TODO: apply scaling factor to the output + axis_tdata <= sm_wavedata; -- axi stream output data, this output should be multiplied by the gain factor, then take the top 16 bits + axis_tvalid <= sm_wavedata_dv; -- axi_stream output data valid + + -- TBD : Generate in state machine? + axis_tlast <= '0'; -- axi_stream output last end channel; \ No newline at end of file diff --git a/src/hdl/pkg/qlaser_dacs_pulse_channel_pkg.vhd b/src/hdl/pkg/qlaser_dacs_pulse_channel_pkg.vhd new file mode 100644 index 0000000..4069325 --- /dev/null +++ b/src/hdl/pkg/qlaser_dacs_pulse_channel_pkg.vhd @@ -0,0 +1,31 @@ +---------------------------------------------------------------------------------------- +-- Project : qlaser FPGA +-- File : qlaser_dacs_pulse_channel.vhd +-- Description : Pulse Channel package file specifying constants +-- Author : eyhc +---------------------------------------------------------------------------------------- +library ieee; +use ieee.std_logic_1164.all; + +package qlaser_dacs_pulse_channel_pkg is +-- Constants declearations +constant C_RAM_SELECT : integer := 11; -- Select bit for which RAM for CPU read/write +-- constant C_NUM_PULSE : integer := 16; -- Number of output data values from pulse RAM (16x24-bit) + +constant C_START_TIME : integer := 24; -- Start time for pulse generation +constant C_BITS_ADDR_START : integer := 12; -- Number of bits for starting address +constant C_BITS_ADDR_LENGTH : integer := 10; -- Number of bits for length address used by an edge of a pulse +constant C_BITS_GAIN_FACTOR : integer := 16; -- Number of bits in gain table +constant C_BITS_TIME_FACTOR : integer := 16; -- Number of bits in time table +constant C_BITS_TIME_INT : integer := 14; -- Starting bit for time integer part of the time factor, counting from MSB +constant C_BITS_TIME_FRAC : integer := 5; -- Starting bit for time fractional part of the time factor, counting from MSB +constant C_BITS_ADDR_TOP : integer := 17; -- Number of bits for the "flat top", the top of the pulse + +constant C_LENGTH_WAVEFORM : integer := 4096; -- Number of output data values from waveform RAM (4kx16-bit) +constant C_BITS_ADDR_WAVE : integer := 16; -- Number of bits in address for waveform RAM + +constant C_BITS_ADDR_PULSE : integer := 10; -- Number of bits in address for pulse definition RAM +constant C_LEN_PULSE : integer := 2**C_BITS_ADDR_PULSE; -- Numbers of address for pulse definition RAM +constant C_PC_INCR : integer := 4; + -- Width of pulse counter increment +end package qlaser_dacs_pulse_channel_pkg; \ No newline at end of file diff --git a/src/hdl/tb/tb_cpubus_dacs_pulse_channel.vhdl b/src/hdl/tb/tb_cpubus_dacs_pulse_channel.vhdl index 6fd800d..d538235 100644 --- a/src/hdl/tb/tb_cpubus_dacs_pulse_channel.vhdl +++ b/src/hdl/tb/tb_cpubus_dacs_pulse_channel.vhdl @@ -14,6 +14,7 @@ use ieee.std_logic_1164.all; use std.textio.all; use work.std_iopak.all; +use work.qlaser_dacs_pulse_channel_pkg.all; entity tb_cpubus_dacs_pulse_channel is @@ -325,8 +326,17 @@ begin -- Reset and drive CPU bus ------------------------------------------------------------- pr_main : process - variable v_ndata32 : integer := 0; - variable v_ndata16 : integer := 0; + variable v_ndata32 : integer := 0; + variable v_ndata16 : integer := 0; + + -- "global" variables for base definitions of each pulses, all pulses are based on these but scaled/offset a bit + variable v_pulsetime : integer := 0; -- For 24-bit pulse time + variable v_timefactor : real := 0.0; -- For 16-bit fixed point timestep + variable v_gainfactor : real := 0.0; -- For 16-bit fixed point gain + variable v_wavestartaddr : integer := 0; -- For 12-bit address i.e. 1024 point waveform RAM + variable v_wavesteps : integer := 0; -- For 10-bit number of steps i.e. 0 = 1 step, X"3FF" = 1024 points + variable v_wavetopwidth : integer := 0; -- For 17-bit number of clock cycles in top of waveform + begin -- Reset reset <= '1'; @@ -356,7 +366,15 @@ begin v_ndata32 := 128; -- Time for first pulse cpu_print_msg("Load pulse RAM"); for NADDR in 0 to 255 loop - cpu_write_pulsedef(clk, NADDR*4, v_ndata32 + (NADDR*(1024+32)), 1.0, 1.0, 0, NADDR*32, 128, cpu_sel, cpu_wr, cpu_addr, cpu_wdata); + -- TODO: In the real setting should we have the python script to check those parameters to make sure they are valid and non-overlapping? + v_pulsetime := v_ndata32 + (NADDR*(1024+32)); + v_timefactor := 1.0; + v_gainfactor := 1.0; + v_wavestartaddr := 0; + v_wavesteps := (NADDR+1)*32; + v_wavetopwidth := 0; -- TODO: EricToGeoff/Sara: in the real settings do we have a case of no flat top? + -- cpu_write_pulsedef(clk, NADDR*4, v_ndata32 + (NADDR*(1024+32)), 1.0, 1.0, 0, NADDR*32, 128, cpu_sel, cpu_wr, cpu_addr, cpu_wdata); + cpu_write_pulsedef(clk, NADDR*4, v_pulsetime, v_timefactor, v_gainfactor, v_wavestartaddr, v_wavesteps, v_wavetopwidth, cpu_sel, cpu_wr, cpu_addr, cpu_wdata); end loop; cpu_print_msg("Pulse RAM loaded"); clk_delay(20); @@ -368,36 +386,42 @@ begin cpu_print_msg("Load waveform RAM"); v_ndata16 := 1; -- first waveform value for NADDR in 0 to 2047 loop - v_ndata32 := (((v_ndata16+1) * 65536) + v_ndata16); + v_ndata32 := (((v_ndata16) * 2**C_BITS_ADDR_WAVE) + (v_ndata16 - 1)); -- Write two 16-bit values with each write cpu_write(clk, (ADR_RAM_WAVE + NADDR) , v_ndata32, cpu_sel, cpu_wr, cpu_addr, cpu_wdata); v_ndata16 := v_ndata16 + 2; end loop; cpu_print_msg("Waveform RAM loaded"); clk_delay(20); + -- ---------------------------------------------------------------- + -- -- Read back Pulse RAM. + -- -- Comment out if not needed to check CPU R/W + -- ---------------------------------------------------------------- + -- v_ndata32 := 128; -- Time for first pulse + -- for NADDR in 0 to 255 loop + -- v_pulsetime := v_ndata32 + (NADDR*(1024+32)); + -- v_timefactor := 1.0; + -- v_gainfactor := 1.0; + -- v_wavestartaddr := 0; + -- v_wavesteps := NADDR*32; + -- v_wavetopwidth := 0; + -- cpu_read_pulsedef(clk, NADDR*4, v_pulsetime, v_timefactor, v_gainfactor, v_wavestartaddr, v_wavesteps, v_wavetopwidth, cpu_sel, cpu_wr, cpu_addr, cpu_wdata); + -- end loop; + -- clk_delay(20); - ---------------------------------------------------------------- - -- Read back Pulse RAM. - ---------------------------------------------------------------- - v_ndata32 := 128; -- Time for first pulse - for NADDR in 0 to 255 loop - cpu_read_pulsedef(clk, NADDR*4, v_ndata32 + (NADDR*(1024+32)), 1.0, 1.0, 0, NADDR*32, 128, cpu_sel, cpu_wr, cpu_addr, cpu_wdata); - end loop; - clk_delay(20); - - ---------------------------------------------------------------- - -- Read back Waveform RAM - ---------------------------------------------------------------- - v_ndata16 := 1; -- first waveform value - for NADDR in 0 to 2047 loop - v_ndata32 := (((v_ndata16+1) * 65536) + v_ndata16); - cpu_read (clk, ADR_RAM_WAVE + NADDR , std_logic_vector(to_unsigned(v_ndata32, 32)) , cpu_sel, cpu_wr, cpu_addr, cpu_wdata, cpu_rdata, cpu_rdata_dv); - v_ndata16 := v_ndata16 + 2; - end loop; + -- ---------------------------------------------------------------- + -- -- Read back Waveform RAM + -- ---------------------------------------------------------------- + -- v_ndata16 := 1; -- first waveform value + -- for NADDR in 0 to 2047 loop + -- v_ndata32 := (((v_ndata16) * 2**C_BITS_ADDR_WAVE) + (v_ndata16 - 1)); + -- cpu_read (clk, ADR_RAM_WAVE + NADDR , std_logic_vector(to_unsigned(v_ndata32, 32)) , cpu_sel, cpu_wr, cpu_addr, cpu_wdata, cpu_rdata, cpu_rdata_dv); + -- v_ndata16 := v_ndata16 + 2; + -- end loop; - -- Done reg write/read check - cpu_print_msg("RAM readback completed"); - clk_delay(20); + -- -- Done reg write/read check + -- cpu_print_msg("RAM readback completed"); + -- clk_delay(20); ---------------------------------------------------------------- @@ -409,7 +433,7 @@ begin start <= '0'; -- Wait for cnt_time to reach last pulse start time + waveform size - for NCNT in 1 to (128 + 16*(1024+32)+ 1024) loop + for NCNT in 1 to (128 + 256*(1024+32)+ 4096) loop -- TODO: EricToGeoff/Sara: in the real settings do we have a constant amount of time or the total time also vary? if so, how much? cnt_time <= std_logic_vector(unsigned(cnt_time) + 1); clk_delay(0); end loop; diff --git a/tools/sim/run.do b/tools/sim/run.do index b83fb76..4606768 100644 --- a/tools/sim/run.do +++ b/tools/sim/run.do @@ -2,7 +2,7 @@ do compile.do vsim -voptargs="+acc" -lib work tb_cpubus_dacs_pulse_channel -do waves_do/pp_sm.do +do waves_do/pp_sm_wavetables.do view wave view structure diff --git a/tools/sim/vsim_stacktrace.vstf b/tools/sim/vsim_stacktrace.vstf new file mode 100644 index 0000000..fa86656 --- /dev/null +++ b/tools/sim/vsim_stacktrace.vstf @@ -0,0 +1,12 @@ +# Current time Mon Jan 15 15:15:21 2024 +# ModelSim - Intel FPGA Edition Stack Trace +# Program = vsim +# Id = "10.5b" +# Version = "2016.10" +# Date = "Oct 5 2016" +# Platform = win32pe +# Signature = a4da31216fa3031746f0a74423efc007 +# 0 0x004d3b4a: '' +# End of Stack Trace + + diff --git a/tools/sim/waves_do/pp_sm_wavetables.do b/tools/sim/waves_do/pp_sm_wavetables.do new file mode 100644 index 0000000..3d25fef --- /dev/null +++ b/tools/sim/waves_do/pp_sm_wavetables.do @@ -0,0 +1,54 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/clk +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reset +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/busy +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cnt_time +add wave -noupdate -radix binary /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cpu_addr +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cpu_wdata +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cpu_wr +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cpu_sel +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cpu_rdata +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/cpu_rdata_dv +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_pulse_addra +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_pulse_dina +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_pulse_douta +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_pulse_we +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/sm_state +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/pc +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_pulse_addrb +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_pulse_doutb +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_time +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors +add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_flattop +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_wea +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_addra +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_dina +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_douta +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_addrb +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_doutb +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/sm_wavedata +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/sm_wavedata_dv +add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/axis_tdata +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/axis_tvalid +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/axis_tlast +add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/axis_tready +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {468198791399 fs} 0} +quietly wave cursor active 1 +configure wave -namecolwidth 163 +configure wave -valuecolwidth 99 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits fs +update +WaveRestoreZoom {468135557347 fs} {468308654877 fs}