first sccuessful scale

This commit is contained in:
Eric Yu 2024-01-23 16:13:00 -08:00
parent cbd8ca6215
commit a0c05457c9
7 changed files with 632 additions and 66 deletions

3
.vscode/settings.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"digital-ide.dont-show-again.propose.issue": true
}

View File

@ -7,7 +7,6 @@ use ieee.std_logic_1164.all;
use ieee.numeric_std.all; use ieee.numeric_std.all;
use work.qlaser_pkg.all; use work.qlaser_pkg.all;
use work.qlaser_dacs_pulse_channel_pkg.all;
entity qlaser_dacs_pulse_channel is entity qlaser_dacs_pulse_channel is
port ( port (
@ -40,6 +39,26 @@ end entity;
-- Single channel pulse generator with two RAMs -- Single channel pulse generator with two RAMs
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
architecture channel of qlaser_dacs_pulse_channel is 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 declarations for pulse RAM
signal ram_pulse_we : std_logic_vector( 0 downto 0); -- Write enable 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 signal ram_pulse_addra : std_logic_vector( 9 downto 0); -- Address for pulse RAM
@ -72,8 +91,8 @@ signal sm_state : t_sm_state;
signal sm_wavedata : std_logic_vector(15 downto 0); -- Waveform RAM data signal sm_wavedata : std_logic_vector(15 downto 0); -- Waveform RAM data
signal sm_wavedata_dv : std_logic; -- Signal to indicate that waveform RAM data is valid signal sm_wavedata_dv : std_logic; -- Signal to indicate that waveform RAM data is valid
signal sm_busy : std_logic; -- Signal to indicate that s.m. is not idle signal sm_busy : std_logic; -- Signal to indicate that s.m. is not idle
signal cnt_wave_len : std_logic_vector(C_BITS_ADDR_LENGTH - 1 downto 0); -- Counter used for incremnet/decrement wave table addresses signal cnt_wave_len : unsigned(C_BITS_ADDR_LENGTH - 1 downto 0); -- Counter used for incremnet/decrement wave table addresses
signal cnt_wave_top : std_logic_vector(C_BITS_ADDR_TOP - 1 downto 0); -- Counter for the flat top of the waveform signal cnt_wave_top : unsigned(C_BITS_ADDR_TOP - 1 downto 0); -- Counter for the flat top of the waveform
-- Misc signals -- Misc signals
signal cpu_rdata_dv_e1 : std_logic; signal cpu_rdata_dv_e1 : std_logic;
@ -92,9 +111,11 @@ signal pc : std_logic_vector(C_BITS_ADDR_PULSE - 1 downto 0);
-- 4. Flat-top 17-bit. [16:0] -- 4. Flat-top 17-bit. [16:0]
---------------------------------------------------------------- ----------------------------------------------------------------
signal reg_pulse_time : std_logic_vector(31 downto 0); -- first register which stores the pulse's start time signal reg_pulse_time : std_logic_vector(31 downto 0); -- first register which stores the pulse's start time
signal reg_pulse_sizes : std_logic_vector(31 downto 0); -- second register which stores the pulse's length, the bit width should increase with the amount of addresses the wavetable has, and its start address signal reg_wave_start_addr : std_logic_vector(C_BITS_ADDR_START -1 downto 0); -- the start address of the wavetable
signal reg_pulse_factors : std_logic_vector(31 downto 0); -- third register which stores the pulse's amplitude and time scale factors signal reg_wave_length : unsigned( 9 downto 0); -- the length of the wavetable
signal reg_pulse_flattop : std_logic_vector(31 downto 0); -- fourth register which stores the pulse's flat top value signal reg_scale_gain : unsigned(15 downto 0); -- scale factor for the gain, amplitude
signal reg_scale_time : unsigned(15 downto 0); -- scale factor for the time, length
signal reg_pulse_flattop : unsigned(C_BITS_ADDR_TOP - 1 downto 0); -- fourth register which stores the pulse's flat top value
-- Pipeline delays -- Pipeline delays
signal start_d1 : std_logic; signal start_d1 : std_logic;
@ -279,9 +300,6 @@ begin
-- or until the maximum counter time has been reached. -- or until the maximum counter time has been reached.
---------------------------------------------------------------- ----------------------------------------------------------------
pr_sm : process (reset, clk) pr_sm : process (reset, clk)
variable v_amp_factor : std_logic_vector(C_BITS_GAIN_FACTOR - 1 downto 0);
variable v_time_factor : std_logic_vector(C_BITS_TIME_FACTOR - 1 downto 0);
-- Temp variables for waveform output -- Temp variables for waveform output
variable v_ram_waveform_doutb_multiplied : std_logic_vector(C_BITS_GAIN_FACTOR + 15 downto 0); variable v_ram_waveform_doutb_multiplied : std_logic_vector(C_BITS_GAIN_FACTOR + 15 downto 0);
begin begin
@ -294,10 +312,11 @@ begin
sm_wavedata <= (others=>'0'); sm_wavedata <= (others=>'0');
sm_wavedata_dv <= '0'; sm_wavedata_dv <= '0';
sm_busy <= '0'; sm_busy <= '0';
reg_wave_start_addr <= (others=>'0');
reg_wave_length <= (others=>'0');
reg_scale_gain <= (others=>'0');
reg_scale_time <= (others=>'0');
reg_pulse_time <= (others=>'0'); reg_pulse_time <= (others=>'0');
reg_pulse_sizes <= (others=>'0');
reg_pulse_factors <= (others=>'0');
reg_pulse_flattop <= (others=>'0'); reg_pulse_flattop <= (others=>'0');
pc <= (others=>'0'); pc <= (others=>'0');
@ -356,19 +375,14 @@ begin
-- Load the pulse channel RAM addresses and start the waveform output -- Load the pulse channel RAM addresses and start the waveform output
sm_busy <= '1'; sm_busy <= '1';
-- Pipline the pulse definition address -- Pipline the pulse definition address
-- TODO: is it better to make a counter to count the quarter or just mod 4?
-- TODO: maybe C-slow around the pulse ram to get it down to 1 cycle??
if (unsigned(ram_pulse_addrb) mod 4 = 0) then if (unsigned(ram_pulse_addrb) mod 4 = 0) then
ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 1); ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 1);
sm_state <= S_LOAD; sm_state <= S_LOAD;
-- first quarter of the pulse definition, no register is loaded -- first quarter of the pulse definition, no register is loaded
-- reg_pulse_time <= ram_pulse_doutb;
elsif (unsigned(ram_pulse_addrb) mod 4 = 1) then elsif (unsigned(ram_pulse_addrb) mod 4 = 1) then
ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 2); ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 2);
sm_state <= S_LOAD; sm_state <= S_LOAD;
-- reg_pulse_sizes <= ram_pulse_doutb;
-- second quarter of the pulse definition, the start time is loaded -- second quarter of the pulse definition, the start time is loaded
reg_pulse_time <= ram_pulse_doutb; reg_pulse_time <= ram_pulse_doutb;
@ -376,19 +390,17 @@ begin
elsif (unsigned(ram_pulse_addrb) mod 4 = 2) then elsif (unsigned(ram_pulse_addrb) mod 4 = 2) then
ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 3); ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 3);
sm_state <= S_LOAD; sm_state <= S_LOAD;
-- reg_pulse_factors <= ram_pulse_doutb;
-- third quarter of the pulse definition, the length and start address of the wavetable are loaded -- third quarter of the pulse definition, the length and start address of the wavetable are loaded
reg_pulse_sizes <= ram_pulse_doutb; reg_wave_start_addr <= ram_pulse_doutb(C_BITS_ADDR_START - 1 downto 0);
reg_wave_length <= unsigned(ram_pulse_doutb(25 downto 16)); -- TODO: make this a constant
elsif (unsigned(ram_pulse_addrb) mod 4 = 3) then elsif (unsigned(ram_pulse_addrb) mod 4 = 3) then
-- ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 4);
sm_state <= S_WAIT; -- address is on the forth word of the entry, the loading process is complete. Moving onto the next state sm_state <= S_WAIT; -- address is on the forth word of the entry, the loading process is complete. Moving onto the next state
-- hold the last pulse definition address as it will be used in the next state -- hold the last pulse definition address as it will be used in the next state
-- reg_pulse_flattop <= ram_pulse_doutb;
pc <= std_logic_vector(unsigned(pc) + C_PC_INCR); -- incremnet the pulse counter and start waiting to output the wave pc <= std_logic_vector(unsigned(pc) + C_PC_INCR); -- incremnet the pulse counter and start waiting to output the wave
-- forth quarter of the pulse definition, the scale factors are loaded -- forth quarter of the pulse definition, the scale factors are loaded
reg_pulse_factors <= ram_pulse_doutb; reg_scale_gain <= unsigned(ram_pulse_doutb(31 downto 16));
reg_scale_time <= unsigned(ram_pulse_doutb(15 downto 0));
end if; end if;
@ -405,17 +417,14 @@ begin
------------------------------------------------------------------------ ------------------------------------------------------------------------
when S_WAIT => when S_WAIT =>
-- read the last word of the pulse definition, the flat top value -- read the last word of the pulse definition, the flat top value
reg_pulse_flattop <= ram_pulse_doutb; reg_pulse_flattop <= unsigned(ram_pulse_doutb(C_BITS_ADDR_TOP - 1 downto 0));
-- Start to output wave and increment pulse position RAM address -- Start to output wave and increment pulse position RAM address
if (reg_pulse_time(C_START_TIME - 1 downto 0) = cnt_time) then if (reg_pulse_time(C_START_TIME - 1 downto 0) = cnt_time) then
sm_state <= S_WAVE_UP; sm_state <= S_WAVE_UP;
-- set the wavetable's address to the starting address defined from the pulse ram -- set the wavetable's address to the starting address defined from the pulse ram
ram_waveform_addrb <= reg_pulse_sizes(C_BITS_ADDR_START - 1 downto 0); ram_waveform_addrb <= reg_wave_start_addr;
-- reset the wave lenth counter -- reset the wave lenth counter
cnt_wave_len <= (others=>'0'); cnt_wave_len <= (others=>'0');
-- parse the scale factors from reg_pulse_factors register
v_time_factor := reg_pulse_factors(C_BITS_TIME_FACTOR - 1 downto 0);
v_amp_factor := reg_pulse_factors(31 downto 16);
elsif (cnt_time = X"FFFFFF") then elsif (cnt_time = X"FFFFFF") then
sm_state <= S_IDLE; sm_state <= S_IDLE;
end if; end if;
@ -427,21 +436,32 @@ begin
------------------------------------------------------------------------ ------------------------------------------------------------------------
when S_WAVE_UP => when S_WAVE_UP =>
-- Check if is end of rise of the waveform, and hold the address -- Check if is end of rise of the waveform, and hold the address
-- TODO: convert the numbers below to constaint. right now just make sure I'm not confused -- TODO: convert the numbers below to constaint. right now just make sure I'm not confused
if (cnt_wave_len = reg_pulse_sizes(25 downto 16)) then if (cnt_wave_len = reg_wave_length) then
-- skip the flat top state if the flat top value is zero
if (reg_pulse_flattop = 0) then
sm_state <= S_WAVE_DOWN;
-- reset the counter for the next transition
cnt_wave_len <= (others=>'0');
else
sm_state <= S_WAVE_FLAT; sm_state <= S_WAVE_FLAT;
-- reset counters for transitions -- reset the counter for the next transition
cnt_wave_len <= (others=>'0'); cnt_wave_len <= (others=>'0');
cnt_wave_top <= (others=>'0'); cnt_wave_top <= (others=>'0');
-- TODO: toSara: do we need to consider the even of no flat top? end if;
-- -- reset counters for transitions
-- cnt_wave_len <= (others=>'0');
-- cnt_wave_top <= (others=>'0');
else else
cnt_wave_len <= std_logic_vector(unsigned(cnt_wave_len) + 1); cnt_wave_len <= cnt_wave_len + 1;
ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) + 1); ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) + 1);
end if; end if;
v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * unsigned(v_amp_factor)); -- sm_wavedata <= std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain)(31 downto 16);
sm_wavedata <= v_ram_waveform_doutb_multiplied(31 downto 16); -- Modelsim Cannot synthesize this above line, so we *have to* seperate them into two lines
-- # ** Error: Prefix of slice name cannot be type conversion (STD_LOGIC_VECTOR) expression.
v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain);
sm_wavedata <= v_ram_waveform_doutb_multiplied(30 downto 15);
sm_wavedata_dv <= '1'; sm_wavedata_dv <= '1';
------------------------------------------------------------------------ ------------------------------------------------------------------------
@ -450,15 +470,15 @@ begin
------------------------------------------------------------------------ ------------------------------------------------------------------------
when S_WAVE_FLAT => when S_WAVE_FLAT =>
-- count the 17-bit flat top, if the counter reaches the flat top value, then go to the next state -- count the 17-bit flat top, if the counter reaches the flat top value, then go to the next state
if (cnt_wave_top = reg_pulse_flattop(C_BITS_ADDR_TOP - 1 downto 0)) then if (cnt_wave_top = reg_pulse_flattop) then
sm_state <= S_WAVE_DOWN; sm_state <= S_WAVE_DOWN;
-- reset the counter for the next transition -- reset the counter for the next transition
cnt_wave_top <= (others=>'0'); cnt_wave_top <= (others=>'0');
else else
cnt_wave_top <= std_logic_vector(unsigned(cnt_wave_top) + 1); cnt_wave_top <= cnt_wave_top + 1;
end if; end if;
v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * unsigned(v_amp_factor)); v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain);
sm_wavedata <= v_ram_waveform_doutb_multiplied(31 downto 16); sm_wavedata <= v_ram_waveform_doutb_multiplied(30 downto 15);
sm_wavedata_dv <= '1'; sm_wavedata_dv <= '1';
------------------------------------------------------------------------ ------------------------------------------------------------------------
@ -469,7 +489,7 @@ begin
-- End of waveform? -- End of waveform?
-- TODO: convert the numbers below to constaint. right now just make sure I'm not confused -- TODO: convert the numbers below to constaint. right now just make sure I'm not confused
if (cnt_wave_len = reg_pulse_sizes(25 downto 16)) then if (cnt_wave_len = reg_wave_length) then
-- If the end of the pulse table is reached then go to idle, increment pulse address for the next waveform otherwise -- If the end of the pulse table is reached then go to idle, increment pulse address for the next waveform otherwise
if (ram_pulse_addrb = std_logic_vector(to_unsigned(C_LEN_PULSE-1, C_BITS_ADDR_PULSE))) then if (ram_pulse_addrb = std_logic_vector(to_unsigned(C_LEN_PULSE-1, C_BITS_ADDR_PULSE))) then
@ -486,11 +506,11 @@ begin
-- Output waveform from RAM with decremented address -- Output waveform from RAM with decremented address
else else
cnt_wave_len <= std_logic_vector(unsigned(cnt_wave_len) + 1); cnt_wave_len <= cnt_wave_len + 1;
ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) - 1); ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) - 1);
end if; end if;
v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * unsigned(v_amp_factor)); v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain);
sm_wavedata <= v_ram_waveform_doutb_multiplied(31 downto 16); sm_wavedata <= v_ram_waveform_doutb_multiplied(30 downto 15);
sm_wavedata_dv <= '1'; sm_wavedata_dv <= '1';
------------------------------------------------------------------------ ------------------------------------------------------------------------
@ -507,10 +527,10 @@ begin
-- TBD: This should come from a FIFO -- 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: 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 -- TODO: apply scaling factor to the output
-- TODO: data valid bit is not aligned with the data
axis_tdata <= sm_wavedata; -- axi stream output data, this output should be multiplied by the gain factor, then take the top 16 bits 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 axis_tvalid <= sm_wavedata_dv; -- axi_stream output data valid
-- TBD : Generate in state machine? -- TBD : Generate in state machine?
axis_tlast <= '0'; -- axi_stream output last axis_tlast <= '0'; -- axi_stream output last
end channel; end channel;

View File

@ -31,4 +31,5 @@ constant C_PC_INCR : integer := 4;
constant BIT_FRAC : integer := 4; -- Define the number of fractional bits constant BIT_FRAC : integer := 4; -- Define the number of fractional bits
constant BIT_FRAC_GAIN : integer := C_BITS_GAIN_FACTOR - 1; -- Define the number of fractional bits of the gain
end package qlaser_dacs_pulse_channel_pkg; end package qlaser_dacs_pulse_channel_pkg;

View File

@ -137,7 +137,7 @@ begin
-- Convert each field into its std_logic_vector equivalent -- Convert each field into its std_logic_vector equivalent
slv_pulsetime := std_logic_vector(to_unsigned(pulsetime, 24)); slv_pulsetime := std_logic_vector(to_unsigned(pulsetime, 24));
slv_timefactor := std_logic_vector(to_unsigned(integer(timefactor * real(2**BIT_FRAC)), 16)); -- Convert real to std_logic_vector keeping the fractional part slv_timefactor := std_logic_vector(to_unsigned(integer(timefactor * real(2**BIT_FRAC)), 16)); -- Convert real to std_logic_vector keeping the fractional part
slv_gainfactor := std_logic_vector(to_unsigned(integer(gainfactor * real(2**BIT_FRAC)), 16)); -- Convert real to std_logic_vector keeping the fractional part slv_gainfactor := std_logic_vector(to_unsigned(integer(gainfactor * real(2**BIT_FRAC_GAIN)), 16)); -- Convert real to std_logic_vector keeping the fractional part
slv_wavestartaddr := std_logic_vector(to_unsigned(wavestartaddr, 12)); slv_wavestartaddr := std_logic_vector(to_unsigned(wavestartaddr, 12));
slv_wavesteps := std_logic_vector(to_unsigned(wavesteps, 10)); slv_wavesteps := std_logic_vector(to_unsigned(wavesteps, 10));
slv_wavetopwidth := std_logic_vector(to_unsigned(wavetopwidth, 17)); slv_wavetopwidth := std_logic_vector(to_unsigned(wavetopwidth, 17));
@ -229,7 +229,7 @@ begin
-- Convert each field into its std_logic_vector equivalent -- Convert each field into its std_logic_vector equivalent
slv_pulsetime := std_logic_vector(to_unsigned(pulsetime, 24)); slv_pulsetime := std_logic_vector(to_unsigned(pulsetime, 24));
slv_timefactor := std_logic_vector(to_unsigned(integer(timefactor * real(2**BIT_FRAC)), 16)); -- Convert real to std_logic_vector keeping the fractional part slv_timefactor := std_logic_vector(to_unsigned(integer(timefactor * real(2**BIT_FRAC)), 16)); -- Convert real to std_logic_vector keeping the fractional part
slv_gainfactor := std_logic_vector(to_unsigned(integer(gainfactor * real(2**BIT_FRAC)), 16)); -- Convert real to std_logic_vector keeping the fractional part slv_gainfactor := std_logic_vector(to_unsigned(integer(gainfactor * real(2**BIT_FRAC_GAIN)), 16)); -- Convert real to std_logic_vector keeping the fractional part
slv_wavestartaddr := std_logic_vector(to_unsigned(wavestartaddr, 12)); slv_wavestartaddr := std_logic_vector(to_unsigned(wavestartaddr, 12));
slv_wavesteps := std_logic_vector(to_unsigned(wavesteps, 10)); slv_wavesteps := std_logic_vector(to_unsigned(wavesteps, 10));
slv_wavetopwidth := std_logic_vector(to_unsigned(wavetopwidth, 17)); slv_wavetopwidth := std_logic_vector(to_unsigned(wavetopwidth, 17));
@ -369,8 +369,8 @@ begin
v_timefactor := 1.0; v_timefactor := 1.0;
v_gainfactor := 0.5; v_gainfactor := 0.5;
v_wavestartaddr := 0; -- TODO: EricToGeoff/Sara: I assume we want starting address of each wave to be different and non-overlapping, right? v_wavestartaddr := 0; -- TODO: EricToGeoff/Sara: I assume we want starting address of each wave to be different and non-overlapping, right?
v_wavesteps := 1; v_wavesteps := NADDR + 1;
v_wavetopwidth := 0; v_wavetopwidth := 1;
-- 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_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); 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; end loop;

View File

@ -0,0 +1,530 @@
---------------------------------------------------------------
-- File : qlaser_dacs_pulse_channel.vhd
-- Description : Single channel of pulse output
----------------------------------------------------------------
library ieee;
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 (
reset : in std_logic;
clk : in std_logic;
enable : in std_logic; -- Set when DAC interface is running
start : in std_logic; -- Set when pulse generation sequence begins (trigger)
cnt_time : in std_logic_vector(23 downto 0); -- Time since trigger.
busy : out std_logic; -- Status signal
-- CPU interface
cpu_addr : in std_logic_vector(11 downto 0); -- Address input
cpu_wdata : in std_logic_vector(31 downto 0); -- Data input
cpu_wr : in std_logic; -- Write enable
cpu_sel : in std_logic; -- Block select
cpu_rdata : out std_logic_vector(31 downto 0); -- Data output
cpu_rdata_dv : out std_logic; -- Acknowledge output
-- AXI-stream output
axis_tready : in std_logic; -- axi_stream ready from downstream module
axis_tdata : out std_logic_vector(15 downto 0); -- axi stream output data
axis_tvalid : out std_logic; -- axi_stream output data valid
axis_tlast : out std_logic -- axi_stream output set on last data
);
end entity;
---------------------------------------------------------------------------
-- Single channel pulse generator with two RAMs
---------------------------------------------------------------------------
architecture channel of qlaser_dacs_pulse_channel is
-- 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
signal ram_pulse_dina : std_logic_vector(31 downto 0); -- Data for pulse RAM
signal ram_pulse_douta : std_logic_vector(31 downto 0); -- Data out from pulse RAM
signal ram_pulse_addrb : std_logic_vector( 9 downto 0); -- Address for pulse RAM
signal ram_pulse_doutb : std_logic_vector(31 downto 0); -- Data out from pulse RAM
-- Signal declarations for waveform RAM
signal ram_waveform_wea : std_logic_vector( 0 downto 0); -- Write enable for waveform RAM
signal ram_waveform_addra : std_logic_vector(10 downto 0); -- Address for waveform RAM
signal ram_waveform_dina : std_logic_vector(31 downto 0); -- Data for waveform RAM
signal ram_waveform_douta : std_logic_vector(31 downto 0); -- Data out from waveform RAM
signal ram_waveform_addrb : std_logic_vector(11 downto 0); -- Address for waveform RAM
signal ram_waveform_doutb : std_logic_vector(15 downto 0); -- Data out from waveform RAM
-- State variable type declaration for main state machine
-- TODO: add a fetch state to get four address from pd ram?
type t_sm_state is (
S_RESET, -- Wait for 'enable'. Stay here until JESD interface is up and running,
S_IDLE, -- Wait for 'start'
S_WAIT, -- Wait for cnt_time, external input, to match pulse position RAM output
S_LOAD, -- Load the pulse channel RAM addresses and start the waveform output
S_HOLD, -- Hold the last pulse definition address and output its data
S_WAVE_UP, -- Output the rising edge of a waveform
S_WAVE_FLAT,-- Output the flat top part of a waveform
S_WAVE_DOWN -- Output the falling edge of a waveform
);
signal sm_state : t_sm_state;
signal sm_wavedata : std_logic_vector(15 downto 0); -- Waveform RAM data
signal sm_wavedata_dv : std_logic; -- Signal to indicate that waveform RAM data is valid
signal sm_busy : std_logic; -- Signal to indicate that s.m. is not idle
signal cnt_wave_len : unsigned(C_BITS_ADDR_LENGTH - 1 downto 0); -- Counter used for incremnet/decrement wave table addresses
signal cnt_wave_top : unsigned(C_BITS_ADDR_TOP - 1 downto 0); -- Counter for the flat top of the waveform
-- Misc signals
signal cpu_rdata_dv_e1 : std_logic;
signal cpu_rdata_dv_e2 : std_logic;
signal cpu_rdata_ramsel_d1 : std_logic;
signal cpu_rdata_ramsel_d2 : std_logic;
signal pc : std_logic_vector(C_BITS_ADDR_PULSE - 1 downto 0); -- pulse counter, used to count the number of pulses generated
----------------------------------------------------------------
-- Assign values from the pulse definition ram to regfiles (?) with the following:
-- 1. Start time 24 bits. [23:0]
-- 2. Wave start addr 12 bit at [11:0]
-- Wave length 10-bit at [25:16]
-- 3. Scale factors 16, 16. [31:16] [15:0]
-- 4. Flat-top 17-bit. [16:0]
----------------------------------------------------------------
signal reg_start_time : std_logic_vector(23 downto 0); -- first register which stores the pulse's start time
signal reg_pulse_sizes : std_logic_vector(31 downto 0); -- second register which stores the pulse's length, the bit width should increase with the amount of addresses the wavetable has, and its start address
-- TODO: replace the above one w/ below two
signal reg_wave_start_addr : std_logic_vector(11 downto 0); -- the start address of the wavetable
signal reg_wave_length : unsigned(9 downto 0); -- the length of the wavetable
signal reg_pulse_factors : std_logic_vector(31 downto 0); -- third register which stores the pulse's amplitude and time scale factors
-- TODO: replace the above one w/ below two
signal reg_scale_gain : unsigned(15 downto 0); -- scale factor for the gain, amplitude
signal reg_scale_time : unsigned(15 downto 0); -- scale factor for the time, length
signal reg_flattop : std_logic_vector(16 downto 0); -- fourth register which stores the pulse's flat top value
-- Pipeline delays
signal start_d1 : std_logic;
signal enable_d1 : std_logic;
begin
----------------------------------------------------------------
-- Pulse Definition Block RAM.
-- Synch write, Synch read
-- Port A is for CPU read/write. 1024x32-bit
-- Port B is for pulse time data output. 1024x32-bit
----------------------------------------------------------------
u_ram_pulse : entity work.bram_pulse_definition
port map(
-- Port A CPU Bus
clka => clk, -- input std_logic
wea => ram_pulse_we, -- input slv( 0 to 0 )
addra => ram_pulse_addra, -- input slv( 9 downto 0 )
dina => ram_pulse_dina, -- input slv( 31 downto 0 )
douta => ram_pulse_douta, -- output slv( 31 downto 0 ),
-- Port B waveform input
clkb => clk,
web => (others=>'0'),
addrb => ram_pulse_addrb, -- input slv( 9 downto 0 )
dinb => (others=>'0'),
doutb => ram_pulse_doutb -- output slv( 31 downto 0 )
);
----------------------------------------------------------------
-- Waveform table Block RAM.
-- Synch write, Synch read
-- Port A is for CPU read/write. 2048x32-bit
-- Port B is for waveform data. 4096x16-bit
----------------------------------------------------------------
u_ram_waveform : entity work.bram_waveform
port map (
-- Port A CPU Bus
clka => clk , -- input std_logic
wea => ram_waveform_wea , -- input slv(0 downto 0)
addra => ram_waveform_addra , -- input slv(10 downto 0)
dina => ram_waveform_dina , -- input slv(31 downto 0)
douta => ram_waveform_douta , -- output slv(31 downto 0)
-- Port B waveform output
clkb => clk , -- input std_logic
web => (others=>'0') , -- input slv(0 downto 0)
addrb => ram_waveform_addrb , -- input slv(11 downto 0)
dinb => (others=>'0') , -- input slv(15 downto 0)
doutb => ram_waveform_doutb -- output slv(15 downto 0)
);
----------------------------------------------------------------
-- CPU Read/Write RAM
-- MSB of cpu_addr is used to select one of the two RAMs
-- to read/write, and the remainder are a 9-bit or 4-bit RAM address.
----------------------------------------------------------------
pr_ram_rw : process (reset, clk)
begin
if (reset = '1') then
ram_pulse_addra <= (others=>'0');
ram_pulse_dina <= (others=>'0');
ram_pulse_we <= (others=>'0');
ram_waveform_wea <= (others=>'0');
ram_waveform_addra <= (others=>'0');
ram_waveform_dina <= (others=>'0');
cpu_rdata <= (others=>'0');
cpu_rdata_dv <= '0';
cpu_rdata_dv_e1 <= '0';
cpu_rdata_dv_e2 <= '0';
cpu_rdata_ramsel_d1 <= '0';
cpu_rdata_ramsel_d2 <= '0';
elsif rising_edge(clk) then
-------------------------------------------------
-- CPU writing RAM
-------------------------------------------------
if (cpu_wr = '1') and (cpu_sel = '1') then
-- 0 for pulse definition, 1 for waveform table
if (cpu_addr(C_RAM_SELECT) = '1') then
ram_pulse_addra <= (others=>'0');
ram_pulse_dina <= (others=>'0');
ram_pulse_we <= (others=>'0');
ram_waveform_wea(0) <= '1';
ram_waveform_addra <= cpu_addr(10 downto 0);
ram_waveform_dina <= cpu_wdata;
else
ram_pulse_addra <= cpu_addr(9 downto 0);
ram_pulse_dina <= cpu_wdata;
ram_pulse_we(0) <= '1';
ram_waveform_wea <= (others=>'0');
ram_waveform_addra <= (others=>'0');
ram_waveform_dina <= (others=>'0');
end if;
cpu_rdata_dv_e1 <= '0';
cpu_rdata_dv_e2 <= '0';
cpu_rdata_ramsel_d1 <= '0';
cpu_rdata_ramsel_d2 <= '0';
-------------------------------------------------
-- CPU read
-------------------------------------------------
elsif (cpu_wr = '0') and (cpu_sel = '1') then
if (cpu_addr(C_RAM_SELECT) = '1') then -- Waveform
ram_pulse_addra <= (others=>'0');
ram_waveform_addra <= cpu_addr(10 downto 0);
else -- Pulse
ram_pulse_addra <= cpu_addr(9 downto 0);
ram_waveform_addra <= (others=>'0');
end if;
ram_pulse_we <= (others=>'0');
ram_waveform_wea(0) <= '0';
cpu_rdata_dv_e2 <= '1'; -- DV for cycle, when RAM output occurs
cpu_rdata_dv_e1 <= cpu_rdata_dv_e2; -- DV for next cycle
cpu_rdata_ramsel_d1 <= cpu_addr(C_RAM_SELECT); -- Save the select bit one cycle later
cpu_rdata_ramsel_d2 <= cpu_rdata_ramsel_d1;
else
ram_pulse_addra <= (others=>'0');
ram_pulse_we <= (others=>'0');
ram_waveform_addra <= (others=>'0');
ram_waveform_wea(0) <= '0';
cpu_rdata_dv_e2 <= '0';
cpu_rdata_dv_e1 <= cpu_rdata_dv_e2; -- DV for next cycle
cpu_rdata_ramsel_d1 <= '0';
cpu_rdata_ramsel_d2 <= cpu_rdata_ramsel_d1;
end if;
-------------------------------------------------
-- Output the delayed RAM data
-- This adds a pipeline delay to the cpu_rdata_dv to account for
-- the delay in reading data from the RAM
-------------------------------------------------
if (cpu_rdata_dv_e1 = '1') then
cpu_rdata_dv <= '1';
-- Select source of output data
if (cpu_rdata_ramsel_d2 = '1') then -- Output is from waveform table
cpu_rdata <= ram_waveform_douta;
elsif (cpu_rdata_ramsel_d2 = '0') then
cpu_rdata <= ram_pulse_douta;
end if;
else
cpu_rdata <= (others=>'0');
cpu_rdata_dv <= '0';
end if;
end if;
end process;
----------------------------------------------------------------
-- State machine:
-- Compares cnt_time input against current output from pulse position RAM.
-- When values match iti incremnts the pulse postion RAM address to
-- retrieve the next pulse position and also starts reading the
-- entire waveform table, one value every clock cycle, until it reaches the end.
-- Once the pulse is complete it waits for the next cnt_time match.
-- Repeat until all pulse position RAM times have triggered a pulse output
-- or until the maximum counter time has been reached.
----------------------------------------------------------------
pr_sm : process (reset, clk)
variable v_amp_factor : std_logic_vector(C_BITS_GAIN_FACTOR - 1 downto 0);
variable v_time_factor : std_logic_vector(C_BITS_TIME_FACTOR - 1 downto 0);
-- Temp variables for waveform output
variable v_ram_waveform_doutb_multiplied : std_logic_vector(C_BITS_GAIN_FACTOR + 15 downto 0);
begin
if (reset = '1') then
sm_state <= S_IDLE; -- TODO: Eric: Should this be S_RESET since we reset the JEDS interface as well?
ram_pulse_addrb <= (others=>'0');
ram_waveform_addrb <= (others=>'0');
sm_wavedata <= (others=>'0');
sm_wavedata_dv <= '0';
sm_busy <= '0';
reg_start_time <= (others=>'0');
reg_pulse_sizes <= (others=>'0');
reg_pulse_factors <= (others=>'0');
reg_flattop <= (others=>'0');
reg_scale_gain <= (others=>'0');
reg_scale_time <= (others=>'0');
pc <= (others=>'0');
cnt_wave_len <= (others=>'0');
cnt_wave_top <= (others=>'0');
elsif rising_edge(clk) then
-- Pipeline delays to use for rising edge detection
enable_d1 <= enable;
start_d1 <= start;
-- Default
sm_wavedata <= (others=>'0');
sm_wavedata_dv <= '0';
------------------------------------------------------------------------
-- Main state machine
------------------------------------------------------------------------
case sm_state is
------------------------------------------------------------------------
-- Wait for rising edge of enable
-- This is set when the JESD interface is aligned and functional.
-- Send a zero value to initialize the DAC then go to idle.
------------------------------------------------------------------------
when S_RESET =>
if (enable = '1') and (enable_d1 = '0') then
sm_wavedata <= (others=>'0');
sm_wavedata_dv <= '1';
sm_state <= S_IDLE;
end if;
sm_busy <= '0';
------------------------------------------------------------------------
-- Wait for rising edge of 'start'.
-- No data output.
------------------------------------------------------------------------
when S_IDLE =>
if (start = '1') and (start_d1 = '0') then
sm_state <= S_LOAD;
sm_busy <= '1';
else
sm_busy <= '0';
end if;
------------------------------------------------------------------------
-- Load four addresses from pulse definition RAM into four 32 bits regesters
------------------------------------------------------------------------
when S_LOAD =>
-- TODO: Eric: does is needed here? or should be inside the if-else loops
-- Load the pulse channel RAM addresses and start the waveform output
sm_busy <= '1';
-- Pipline the pulse definition address
-- TODO: is it better to make a counter to count the quarter or just mod 4?
-- TODO: maybe C-slow around the pulse ram to get it down to 1 cycle??
if (unsigned(ram_pulse_addrb) mod 4 = 0) then
ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 1);
sm_state <= S_LOAD;
-- first quarter of the pulse definition, no register is loaded
-- reg_start_time <= ram_pulse_doutb;
elsif (unsigned(ram_pulse_addrb) mod 4 = 1) then
ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 2);
sm_state <= S_LOAD;
-- reg_pulse_sizes <= ram_pulse_doutb;
-- second quarter of the pulse definition, the start time is loaded
reg_start_time <= ram_pulse_doutb;
elsif (unsigned(ram_pulse_addrb) mod 4 = 2) then
ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 3);
sm_state <= S_LOAD;
-- reg_pulse_factors <= ram_pulse_doutb;
-- third quarter of the pulse definition, the length and start address of the wavetable are loaded
reg_pulse_sizes <= ram_pulse_doutb;
elsif (unsigned(ram_pulse_addrb) mod 4 = 3) then
-- ram_pulse_addrb <= std_logic_vector(unsigned(pc) + 4);
sm_state <= S_WAIT; -- address is on the forth word of the entry, the loading process is complete. Moving onto the next state
-- hold the last pulse definition address as it will be used in the next state
-- reg_flattop <= ram_pulse_doutb;
pc <= std_logic_vector(unsigned(pc) + C_PC_INCR); -- incremnet the pulse counter and start waiting to output the wave
-- forth quarter of the pulse definition, the scale factors are loaded
reg_pulse_factors <= ram_pulse_doutb;
reg_scale_gain <= unsigned(ram_pulse_doutb(31 downto 16));
reg_scale_time <= unsigned(ram_pulse_doutb(15 downto 0));
end if;
-- ------------------------------------------------------------------------
-- -- Hold the last pulse definition address and output its data for one more clock cycle
-- ------------------------------------------------------------------------
-- when S_HOLD =>
-- sm_state <= S_LOAD;
------------------------------------------------------------------------
-- Wait for cnt_time, external input, to match pulse position RAM output
-- Return to idle state if max time is reached. Output waveform value zero.
------------------------------------------------------------------------
when S_WAIT =>
-- read the last word of the pulse definition, the flat top value
reg_flattop <= ram_pulse_doutb;
-- Start to output wave and increment pulse position RAM address
if (reg_start_time(C_START_TIME - 1 downto 0) = cnt_time) then
sm_state <= S_WAVE_UP;
-- set the wavetable's address to the starting address defined from the pulse ram
ram_waveform_addrb <= reg_pulse_sizes(C_BITS_ADDR_START - 1 downto 0);
-- reset the wave lenth counter
cnt_wave_len <= (others=>'0');
-- parse the scale factors from reg_pulse_factors register
v_time_factor := reg_pulse_factors(C_BITS_TIME_FACTOR - 1 downto 0);
v_amp_factor := reg_pulse_factors(31 downto 16);
elsif (cnt_time = X"FFFFFF") then
sm_state <= S_IDLE;
end if;
------------------------------------------------------------------------
-- Output the raising edge of a waveform
-- Hold the last address when complete
------------------------------------------------------------------------
when S_WAVE_UP =>
-- Check if is end of rise of the waveform, and hold the address
-- TODO: convert the numbers below to constaint. right now just make sure I'm not confused
if (cnt_wave_len = reg_wave_length) then
sm_state <= S_WAVE_FLAT;
-- 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 <= cnt_wave_len + 1;
ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) + 1);
end if;
v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain);
sm_wavedata <= std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain)(31 downto 16);
sm_wavedata_dv <= '1';
------------------------------------------------------------------------
-- Hold the last address and output its data
-- decrement from this address when finished waiting
------------------------------------------------------------------------
when S_WAVE_FLAT =>
-- count the 17-bit flat top, if the counter reaches the flat top value, then go to the next state
if (cnt_wave_top = reg_flattop(C_BITS_ADDR_TOP - 1 downto 0)) then
sm_state <= S_WAVE_DOWN;
-- reset the counter for the next transition
cnt_wave_top <= (others=>'0');
else
cnt_wave_top <= std_logic_vector(unsigned(cnt_wave_top) + 1);
end if;
v_ram_waveform_doutb_multiplied := std_logic_vector(unsigned(ram_waveform_doutb) * unsigned(v_amp_factor));
sm_wavedata <= std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain)(31 downto 16); ;
sm_wavedata_dv <= '1';
------------------------------------------------------------------------
-- Output the falling edge of a waveform
-- Hold the start address when complete
------------------------------------------------------------------------
when S_WAVE_DOWN =>
-- End of waveform?
-- TODO: convert the numbers below to constaint. right now just make sure I'm not confused
if (cnt_wave_len = reg_wave_length) then
-- If the end of the pulse table is reached then go to idle, increment pulse address for the next waveform otherwise
if (ram_pulse_addrb = std_logic_vector(to_unsigned(C_LEN_PULSE-1, C_BITS_ADDR_PULSE))) then
ram_pulse_addrb <= (others=>'0');
pc <= (others=>'0');
sm_state <= S_IDLE;
else -- increment pulse address for the next waveform
ram_pulse_addrb <= pc;
-- the above line will now happen in the load state
-- pc <= std_logic_vector(unsigned(pc) + C_PC_INCR);
sm_state <= S_LOAD;
end if;
-- Output waveform from RAM with decremented address
else
cnt_wave_len <= cnt_wave_len + 1;
ram_waveform_addrb <= std_logic_vector(unsigned(ram_waveform_addrb) - 1);
end if;
sm_wavedata <= std_logic_vector(unsigned(ram_waveform_doutb) * reg_scale_gain)(31 downto 16);
sm_wavedata_dv <= '1';
------------------------------------------------------------------------
-- Default
------------------------------------------------------------------------
when others =>
sm_state <= S_IDLE;
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;

View File

@ -10,3 +10,15 @@
# End of Stack Trace # End of Stack Trace
# Current time Mon Jan 22 14:57:15 2024
# ModelSim - Intel FPGA Edition Stack Trace
# Program = vsim
# Id = "10.5b"
# Version = "2016.10"
# Date = "Oct 5 2016"
# Platform = win32pe
# Signature = a4da31216fa3031746f0a74423efc007
# 0 0x005d9fc7: '<unknown (@0x5d9fc7)>'
# End of Stack Trace

View File

@ -25,25 +25,25 @@ 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 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/ram_pulse_doutb
add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_time add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_time
add wave -noupdate -radix unsigned -childformat {{/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(15) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(14) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(13) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(12) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(11) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(10) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(9) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(8) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(7) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(6) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(5) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(4) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(3) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(2) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(1) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16(0) -radix unsigned}} -subitemconfig {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(31) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(30) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(29) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(28) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(27) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(26) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(25) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(24) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(23) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(22) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(21) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(20) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(19) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(18) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(17) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(16) {-radix unsigned}} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors_31_16
add wave -noupdate -label reg_pulse_factors_15_0 -radix unsigned -childformat {{/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(15) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(14) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(13) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(12) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(11) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(10) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(9) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(8) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(7) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(6) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(5) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(4) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(3) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(2) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(1) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0(0) -radix unsigned}} -subitemconfig {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(15) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(14) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(13) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(12) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(11) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(10) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(9) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(8) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(7) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(6) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(5) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(4) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(3) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(2) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(1) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_factors(0) {-radix unsigned}} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ewg_pulse_factors_15_0
add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_start_addr
add wave -noupdate -radix unsigned -childformat {{/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(9) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(8) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(7) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(6) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(5) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(4) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(3) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(2) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(1) -radix unsigned} {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length(0) -radix unsigned}} -subitemconfig {/tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(25) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(24) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(23) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(22) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(21) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(20) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(19) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(18) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(17) {-radix unsigned} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_sizes(16) {-radix unsigned}} /tb_cpubus_dacs_pulse_channel/u_dac_pulse/wave_length
add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_flattop add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_pulse_flattop
add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_wave_start_addr
add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_wave_length
add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_scale_gain
add wave -noupdate -radix hexadecimal /tb_cpubus_dacs_pulse_channel/u_dac_pulse/reg_scale_time
add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_wea 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_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_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_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_addrb
add wave -noupdate -radix unsigned /tb_cpubus_dacs_pulse_channel/u_dac_pulse/ram_waveform_doutb add wave -noupdate -radix hexadecimal /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 -radix hexadecimal /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 /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 -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_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_tlast
add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/axis_tready add wave -noupdate /tb_cpubus_dacs_pulse_channel/u_dac_pulse/axis_tready
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {739708211940 fs} 0} WaveRestoreCursors {{Cursor 1} {104895000000 fs} 0}
quietly wave cursor active 1 quietly wave cursor active 1
configure wave -namecolwidth 163 configure wave -namecolwidth 163
configure wave -valuecolwidth 99 configure wave -valuecolwidth 99
@ -59,4 +59,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits fs configure wave -timelineunits fs
update update
WaveRestoreZoom {739618451235 fs} {739791548765 fs} WaveRestoreZoom {104768451235 fs} {104941548765 fs}