Commit 57e9bcdf authored by Tristan Gingold's avatar Tristan Gingold

vtu: count pulses on the byte input. Improve testbench.

parent 0428923e
...@@ -28,8 +28,8 @@ memory-map: ...@@ -28,8 +28,8 @@ memory-map:
children: children:
- field: - field:
name: missValid name: missValid
description: Start ignored as no configuration parameters comment: Start ignored as no configuration parameters
comment: > description: >
The start pulse hasn't been transferred to the VTU because The start pulse hasn't been transferred to the VTU because
the parameters were not valid. The configOffline.valid bit the parameters were not valid. The configOffline.valid bit
was set to 0 when the pulse arrived. Changed when the next was set to 0 when the pulse arrived. Changed when the next
...@@ -37,8 +37,8 @@ memory-map: ...@@ -37,8 +37,8 @@ memory-map:
range: 7 range: 7
- field: - field:
name: missReady name: missReady
description: Start ignored as VTU not ready comment: Start ignored as VTU not ready
comment: > description: >
The start pulse hasn't been transferred to the VTU because The start pulse hasn't been transferred to the VTU because
it wasn't ready. Either the RF clock was not present, or it wasn't ready. Either the RF clock was not present, or
the start pulse came too early. Changed when the next the start pulse came too early. Changed when the next
...@@ -46,8 +46,8 @@ memory-map: ...@@ -46,8 +46,8 @@ memory-map:
range: 6 range: 6
- field: - field:
name: startReady name: startReady
description: The VTU is ready to accept the start pulse comment: The VTU is ready to accept the start pulse
comment: > description: >
Should be 1. Set to 0 when a start pulse has been detected Should be 1. Set to 0 when a start pulse has been detected
and not yet transfered to the VTU. If stuck to 0, there is and not yet transfered to the VTU. If stuck to 0, there is
no RF clock. no RF clock.
...@@ -95,8 +95,8 @@ memory-map: ...@@ -95,8 +95,8 @@ memory-map:
type: autoclear type: autoclear
- reg: - reg:
name: configOffline name: configOffline
description: Control signals comment: Control signals
comment: > description: >
The offline registers defines the values for the next start. The offline registers defines the values for the next start.
width: 16 width: 16
access: rw access: rw
...@@ -135,6 +135,7 @@ memory-map: ...@@ -135,6 +135,7 @@ memory-map:
range: 1 range: 1
- field: - field:
name: valid name: valid
comment: Offline values are set
description: > description: >
To be set when all offline values are set and coherent. The To be set when all offline values are set and coherent. The
hardware will use them at the next start. User shouldn't hardware will use them at the next start. User shouldn't
...@@ -144,8 +145,8 @@ memory-map: ...@@ -144,8 +145,8 @@ memory-map:
type: wire type: wire
- reg: - reg:
name: bValueOffline name: bValueOffline
description: Number of RF clock cycles to delay (B) comment: Number of RF clock cycles to delay (B)
comment: > description: >
Used in all modes. The exact number of cycles depend on the mode, Used in all modes. The exact number of cycles depend on the mode,
as there is additional constant delay. as there is additional constant delay.
width: 64 width: 64
...@@ -268,4 +269,4 @@ memory-map: ...@@ -268,4 +269,4 @@ memory-map:
- submap: - submap:
name: trigdiag name: trigdiag
filename: vtudiag_regs.cheby filename: vtudiag_regs.cheby
include: True include: True
\ No newline at end of file
-- Do not edit. Generated on Thu Mar 26 14:20:33 2020 by tgingold -- Do not edit. Generated on Mon May 04 16:51:42 2020 by gingold
-- With Cheby 1.4.dev0 and these options: -- With Cheby 1.4.dev0 and these options:
-- -i trigunit_regs.cheby --gen-hdl trigunit_regs.vhd -- -i trigunit_regs.cheby --gen-hdl trigunit_regs.vhd
...@@ -15,12 +15,12 @@ entity trigunit_regs is ...@@ -15,12 +15,12 @@ entity trigunit_regs is
wb_i : in t_wishbone_slave_in; wb_i : in t_wishbone_slave_in;
wb_o : out t_wishbone_slave_out; wb_o : out t_wishbone_slave_out;
-- VTU status -- Status register of the VTU.
-- The start pulse hasn't been transferred to the VTU because the parameters were not valid. The configOffline.valid bit was set to 0 when the pulse arrived. Changed when the next start pulse is detected. -- Start ignored as no configuration parameters
status_missValid_i : in std_logic; status_missValid_i : in std_logic;
-- The start pulse hasn't been transferred to the VTU because it wasn't ready. Either the RF clock is was not present, or the start pulse came too early. Changed when the next start pulse is detected. -- Start ignored as VTU not ready
status_missReady_i : in std_logic; status_missReady_i : in std_logic;
-- Should be 1. Set to 0 when a start pulse has been detected and not yet transfered to the VTU. If stuck to 0, there is no RF clock. -- The VTU is ready to accept the start pulse
status_startReady_i : in std_logic; status_startReady_i : in std_logic;
-- VTU core running -- VTU core running
status_running_i : in std_logic; status_running_i : in std_logic;
...@@ -44,12 +44,12 @@ entity trigunit_regs is ...@@ -44,12 +44,12 @@ entity trigunit_regs is
configOffline_mode_o : out std_logic_vector(2 downto 0); configOffline_mode_o : out std_logic_vector(2 downto 0);
-- Switch between HT and HT+1 values while running -- Switch between HT and HT+1 values while running
configOffline_htSwitchingEnable_o : out std_logic; configOffline_htSwitchingEnable_o : out std_logic;
-- To be set when all offline values are set. -- Offline values are set
configOffline_valid_i : in std_logic; configOffline_valid_i : in std_logic;
configOffline_valid_o : out std_logic; configOffline_valid_o : out std_logic;
configOffline_wr_o : out std_logic; configOffline_wr_o : out std_logic;
-- Used in all modes -- Number of RF clock cycles to delay (B)
bValueOffline_o : out std_logic_vector(63 downto 0); bValueOffline_o : out std_logic_vector(63 downto 0);
-- Not used in singlePulse and playMemory modes -- Not used in singlePulse and playMemory modes
...@@ -86,8 +86,10 @@ entity trigunit_regs is ...@@ -86,8 +86,10 @@ entity trigunit_regs is
trigODelay_wr_o : out std_logic; trigODelay_wr_o : out std_logic;
-- Control register -- Control register
-- Select the window to measure the frequency. A change to this value is taken into account at the end of the current window. 00: 500us; 01: 50ms; 10: 5s; 11: 20s -- Enable the unit
trigdiag_control_window_o : out std_logic_vector(1 downto 0); trigdiag_control_enable_o : out std_logic;
-- Select the window to measure the frequency. A change to this value is taken into account at the end of the current window. 000: 5us; 010: 500us; 100: 50ms; 101: 5s; 110: 20s 001, 011, 111: unused.
trigdiag_control_window_o : out std_logic_vector(2 downto 0);
-- This register is incremented at the end of the window, when the new frequency is made available. -- This register is incremented at the end of the window, when the new frequency is made available.
trigdiag_generation_i : in std_logic_vector(15 downto 0); trigdiag_generation_i : in std_logic_vector(15 downto 0);
...@@ -111,6 +113,8 @@ architecture syn of trigunit_regs is ...@@ -111,6 +113,8 @@ architecture syn of trigunit_regs is
signal wb_rip : std_logic; signal wb_rip : std_logic;
signal wb_wip : std_logic; signal wb_wip : std_logic;
signal control_vtuReset_reg : std_logic; signal control_vtuReset_reg : std_logic;
signal control_stopSoftTrigger_reg : std_logic;
signal control_startSoftTrigger_reg : std_logic;
signal control_wreq : std_logic; signal control_wreq : std_logic;
signal control_wack : std_logic; signal control_wack : std_logic;
signal configOffline_mode_reg : std_logic_vector(2 downto 0); signal configOffline_mode_reg : std_logic_vector(2 downto 0);
...@@ -128,7 +132,8 @@ architecture syn of trigunit_regs is ...@@ -128,7 +132,8 @@ architecture syn of trigunit_regs is
signal wValueOffline_wack : std_logic_vector(3 downto 0); signal wValueOffline_wack : std_logic_vector(3 downto 0);
signal syncIDelay_wreq : std_logic; signal syncIDelay_wreq : std_logic;
signal trigODelay_wreq : std_logic; signal trigODelay_wreq : std_logic;
signal trigdiag_control_window_reg : std_logic_vector(1 downto 0); signal trigdiag_control_enable_reg : std_logic;
signal trigdiag_control_window_reg : std_logic_vector(2 downto 0);
signal trigdiag_control_wreq : std_logic; signal trigdiag_control_wreq : std_logic;
signal trigdiag_control_wack : std_logic; signal trigdiag_control_wack : std_logic;
signal rd_ack_d0 : std_logic; signal rd_ack_d0 : std_logic;
...@@ -192,16 +197,23 @@ begin ...@@ -192,16 +197,23 @@ begin
-- Register control -- Register control
control_vtuReset_o <= control_vtuReset_reg; control_vtuReset_o <= control_vtuReset_reg;
control_stopSoftTrigger_o <= wr_dat_d0(1) and control_wreq; control_stopSoftTrigger_o <= control_stopSoftTrigger_reg;
control_startSoftTrigger_o <= wr_dat_d0(0) and control_wreq; control_startSoftTrigger_o <= control_startSoftTrigger_reg;
process (clk_i) begin process (clk_i) begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
control_vtuReset_reg <= '1'; control_vtuReset_reg <= '1';
control_stopSoftTrigger_reg <= '0';
control_startSoftTrigger_reg <= '0';
control_wack <= '0'; control_wack <= '0';
else else
if control_wreq = '1' then if control_wreq = '1' then
control_vtuReset_reg <= wr_dat_d0(2); control_vtuReset_reg <= wr_dat_d0(2);
control_stopSoftTrigger_reg <= wr_dat_d0(1);
control_startSoftTrigger_reg <= wr_dat_d0(0);
else
control_stopSoftTrigger_reg <= '0';
control_startSoftTrigger_reg <= '0';
end if; end if;
control_wack <= control_wreq; control_wack <= control_wreq;
end if; end if;
...@@ -321,15 +333,18 @@ begin ...@@ -321,15 +333,18 @@ begin
trigODelay_wr_o <= trigODelay_wreq; trigODelay_wr_o <= trigODelay_wreq;
-- Register trigdiag_control -- Register trigdiag_control
trigdiag_control_enable_o <= trigdiag_control_enable_reg;
trigdiag_control_window_o <= trigdiag_control_window_reg; trigdiag_control_window_o <= trigdiag_control_window_reg;
process (clk_i) begin process (clk_i) begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
trigdiag_control_window_reg <= "00"; trigdiag_control_enable_reg <= '0';
trigdiag_control_window_reg <= "000";
trigdiag_control_wack <= '0'; trigdiag_control_wack <= '0';
else else
if trigdiag_control_wreq = '1' then if trigdiag_control_wreq = '1' then
trigdiag_control_window_reg <= wr_dat_d0(1 downto 0); trigdiag_control_enable_reg <= wr_dat_d0(4);
trigdiag_control_window_reg <= wr_dat_d0(2 downto 0);
end if; end if;
trigdiag_control_wack <= trigdiag_control_wreq; trigdiag_control_wack <= trigdiag_control_wreq;
end if; end if;
...@@ -549,7 +564,7 @@ begin ...@@ -549,7 +564,7 @@ begin
end process; end process;
-- Process for read requests. -- Process for read requests.
process (adr_int, rd_req_int, status_wrongWvalue_i, status_wrongHTvalue_i, status_wrongBvalue_i, status_running_i, status_startReady_i, status_missReady_i, status_missValid_i, configOffline_valid_i, configOffline_htSwitchingEnable_reg, configOffline_mode_reg, bValueOffline_reg, htValueOffline_reg, wValueOffline_reg, configOnline_htSwitchingEnable_i, configOnline_mode_i, bValueOnline_i, htValueOnline_i, wValueOnline_i, syncIDelay_delay_i, trigODelay_delay_i, trigdiag_control_window_reg, trigdiag_generation_i, trigdiag_freq_i, trigdiag_counter_i) begin process (adr_int, rd_req_int, status_wrongWvalue_i, status_wrongHTvalue_i, status_wrongBvalue_i, status_running_i, status_startReady_i, status_missReady_i, status_missValid_i, configOffline_valid_i, configOffline_htSwitchingEnable_reg, configOffline_mode_reg, bValueOffline_reg, htValueOffline_reg, wValueOffline_reg, configOnline_htSwitchingEnable_i, configOnline_mode_i, bValueOnline_i, htValueOnline_i, wValueOnline_i, syncIDelay_delay_i, trigODelay_delay_i, trigdiag_control_window_reg, trigdiag_control_enable_reg, trigdiag_generation_i, trigdiag_freq_i, trigdiag_counter_i) begin
-- By default ack read requests -- By default ack read requests
rd_dat_d0 <= (others => 'X'); rd_dat_d0 <= (others => 'X');
case adr_int(6 downto 3) is case adr_int(6 downto 3) is
...@@ -742,8 +757,10 @@ begin ...@@ -742,8 +757,10 @@ begin
when "0" => when "0" =>
-- Reg trigdiag_control -- Reg trigdiag_control
rd_ack_d0 <= rd_req_int; rd_ack_d0 <= rd_req_int;
rd_dat_d0(1 downto 0) <= trigdiag_control_window_reg; rd_dat_d0(2 downto 0) <= trigdiag_control_window_reg;
rd_dat_d0(15 downto 2) <= (others => '0'); rd_dat_d0(3) <= '0';
rd_dat_d0(4) <= trigdiag_control_enable_reg;
rd_dat_d0(15 downto 5) <= (others => '0');
when "1" => when "1" =>
-- Reg trigdiag_generation -- Reg trigdiag_generation
rd_ack_d0 <= rd_req_int; rd_ack_d0 <= rd_req_int;
......
...@@ -139,8 +139,6 @@ architecture rtl of vtu_blk is ...@@ -139,8 +139,6 @@ architecture rtl of vtu_blk is
signal sync_data_in : std_logic_vector(7 downto 0); signal sync_data_in : std_logic_vector(7 downto 0);
signal sync_data_out : std_logic_vector(7 downto 0); signal sync_data_out : std_logic_vector(7 downto 0);
signal sync_data_pulse : std_logic;
-- Trigger out, before delay. -- Trigger out, before delay.
signal trig_out : std_logic; signal trig_out : std_logic;
...@@ -151,7 +149,8 @@ architecture rtl of vtu_blk is ...@@ -151,7 +149,8 @@ architecture rtl of vtu_blk is
-- Trig delay current value. -- Trig delay current value.
signal trig_odelay_out : std_logic_vector (4 downto 0); signal trig_odelay_out : std_logic_vector (4 downto 0);
signal diag_window : std_logic_vector (1 downto 0); signal diag_enable : std_logic;
signal diag_window : std_logic_vector (2 downto 0);
signal diag_generation : std_logic_vector (15 downto 0); signal diag_generation : std_logic_vector (15 downto 0);
signal diag_freq : std_logic_vector (31 downto 0); signal diag_freq : std_logic_vector (31 downto 0);
signal diag_counter : std_logic_vector (31 downto 0); signal diag_counter : std_logic_vector (31 downto 0);
...@@ -330,15 +329,14 @@ begin ...@@ -330,15 +329,14 @@ begin
d_i => vtu_wrongw, d_i => vtu_wrongw,
q_o => vtu_wrongw_sys); q_o => vtu_wrongw_sys);
sync_data_pulse <= '1' when sync_data_out /= "00000000" else '0';
inst_trig_diag: entity work.vtu_diag inst_trig_diag: entity work.vtu_diag
port map ( port map (
clk_i => clk_sys_i, clk_i => clk_sys_i,
rst_n_i => rst_sys_n, rst_n_i => rst_sys_n,
enable_i => diag_enable,
windows_i => diag_window, windows_i => diag_window,
sig_i => clk_vtu_i, sig_i => clk_vtu_i,
en_i => sync_data_pulse, dat_i => sync_data_out,
freq_o => diag_freq, freq_o => diag_freq,
generation_o => diag_generation, generation_o => diag_generation,
counter_o => diag_counter counter_o => diag_counter
...@@ -388,6 +386,7 @@ begin ...@@ -388,6 +386,7 @@ begin
trigODelay_wr_o => trig_odelay_wr, trigODelay_wr_o => trig_odelay_wr,
trigdiag_control_window_o => diag_window, trigdiag_control_window_o => diag_window,
trigdiag_control_enable_o => diag_enable,
trigdiag_generation_i => diag_generation, trigdiag_generation_i => diag_generation,
trigdiag_freq_i => diag_freq, trigdiag_freq_i => diag_freq,
trigdiag_counter_i => diag_counter); trigdiag_counter_i => diag_counter);
......
...@@ -53,16 +53,15 @@ entity vtu_diag is ...@@ -53,16 +53,15 @@ entity vtu_diag is
-- Signal to be measured. -- Signal to be measured.
sig_i : in std_logic; sig_i : in std_logic;
en_i : in std_logic; dat_i : in std_logic_vector(7 downto 0);
-- Must be set to enable the unit.
enable_i : in std_logic;
-- Select the window to measure the frequency. -- Select the window to measure the frequency.
-- 0: 500us/2kHz
-- 1: 50ms/20Hz
-- 2: 5s/0.2Hz
-- 3: 20s/0.05Hz
-- A change to this value is taken into account at the end of the -- A change to this value is taken into account at the end of the
-- previous value. -- previous value.
windows_i : in std_logic_vector(1 downto 0); windows_i : in std_logic_vector(2 downto 0);
-- Last frequency measured. -- Last frequency measured.
freq_o : out std_logic_vector(31 downto 0); freq_o : out std_logic_vector(31 downto 0);
...@@ -76,7 +75,8 @@ end vtu_diag; ...@@ -76,7 +75,8 @@ end vtu_diag;
architecture arch of vtu_diag is architecture arch of vtu_diag is
signal gate_pulse, gate_pulse_synced : std_logic := '0'; signal gate_pulse : std_logic := '0';
signal gate_pulse_synced, gate_pulse_synced_d : std_logic := '0';
signal cntr_last : unsigned(31 downto 0) := (others => '0'); signal cntr_last : unsigned(31 downto 0) := (others => '0');
signal cntr_gate : unsigned(31 downto 0) := (others => '0'); signal cntr_gate : unsigned(31 downto 0) := (others => '0');
...@@ -87,29 +87,58 @@ architecture arch of vtu_diag is ...@@ -87,29 +87,58 @@ architecture arch of vtu_diag is
signal generation : unsigned (15 downto 0); signal generation : unsigned (15 downto 0);
signal counter : unsigned(31 downto 0); signal enable_sig : std_logic;
signal sig_pulse : std_logic; signal counter : unsigned(31 downto 0);
signal sig_sync : std_logic; signal counter_resync : std_logic_vector(31 downto 0);
signal counter_wr : std_logic;
signal freq_wr : std_logic; signal freq_wr : std_logic;
signal dat_d : std_logic_vector(8 downto 0);
begin begin
assert g_CLK_FREQ mod 2000 = 0 assert g_CLK_FREQ mod 2000 = 0
report "inaccurate results due to clk frequency" report "inaccurate results due to clk frequency"
severity failure; severity failure;
p_pulse_counter: process (sig_i)
begin
if rising_edge(sig_i) then
dat_d <= dat_d(0) & dat_i;
end if;
end process;
-- Mesure number of SIG_I pulses during the window. -- Mesure number of SIG_I pulses during the window.
p_freq_counter : process (sig_i) p_freq_counter : process (sig_i)
variable cnt : natural range 0 to 4;
begin begin
if rising_edge(sig_i) then if rising_edge(sig_i) then
if gate_pulse_synced = '1' then if enable_sig = '0' then
-- End of windows, restart counter. gate_pulse_synced_d <= '0';
freq_reg <= std_logic_vector(cntr_meas); counter <= (others => '0');
freq_reg <= (others => '0');
cntr_meas <= (others => '0'); cntr_meas <= (others => '0');
else else
if en_i = '1' then gate_pulse_synced_d <= gate_pulse_synced;
cntr_meas <= cntr_meas + 1;
-- Count the number of rising edges in dat_d.
cnt := 0;
for i in 7 downto 0 loop
if dat_d(i + 1) = '0' and dat_d (i) = '1' then
cnt := cnt + 1;
end if;
end loop;
if gate_pulse_synced = '1' then
-- End of the window:
-- Save result and restart counter.
freq_reg <= std_logic_vector(cntr_meas);
cntr_meas <= to_unsigned(cnt, 32);
else
cntr_meas <= cntr_meas + cnt;
end if; end if;
counter <= counter + cnt;
end if; end if;
end if; end if;
end process p_freq_counter; end process p_freq_counter;
...@@ -118,18 +147,26 @@ begin ...@@ -118,18 +147,26 @@ begin
p_gate_counter : process(clk_i) p_gate_counter : process(clk_i)
begin begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_n_i = '0' or cntr_gate = cntr_last then if rst_n_i = '0' or enable_i = '0' then
-- Once the reset and enable are released, a pulse start is generated.
cntr_gate <= (others => '0');
cntr_last <= (others => '0');
elsif cntr_gate = cntr_last then
-- End of the window, start a new one. -- End of the window, start a new one.
cntr_gate <= (others => '0'); cntr_gate <= (others => '0');
gate_pulse <= '1'; gate_pulse <= '1';
case windows_i is case windows_i is
when "00" => when "000" =>
cntr_last <= to_unsigned (g_CLK_FREQ / 2000, 32) - 1; -- 5us
when "01" => cntr_last <= to_unsigned (g_CLK_FREQ / 200_000, 32) - 1;
when "010" =>
-- 500us
cntr_last <= to_unsigned (g_CLK_FREQ / 2_000, 32) - 1;
when "100" =>
cntr_last <= to_unsigned (g_CLK_FREQ / 20, 32) - 1; cntr_last <= to_unsigned (g_CLK_FREQ / 20, 32) - 1;
when "10" => when "101" =>
cntr_last <= to_unsigned (g_CLK_FREQ * 5, 32) - 1; cntr_last <= to_unsigned (g_CLK_FREQ * 5, 32) - 1;
when "11" => when "110" =>
cntr_last <= to_unsigned (g_CLK_FREQ * 20, 32) - 1; cntr_last <= to_unsigned (g_CLK_FREQ * 20, 32) - 1;
when others => when others =>
null; null;
...@@ -155,55 +192,55 @@ begin ...@@ -155,55 +192,55 @@ begin
inst_sig_sync : entity work.gc_sync inst_sig_sync : entity work.gc_sync
port map ( port map (
clk_i => clk_i, clk_i => sig_i,
rst_n_a_i => rst_n_i, rst_n_a_i => rst_n_i,
d_i => sig_i, d_i => enable_i,
q_o => sig_sync); q_o => enable_sig);
my_inst: entity work.gc_edge_detect
generic map (
g_async_rst => False,
g_pulse_edge => "positive",
g_clock_edge => "positive"
)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
data_i => sig_sync,
pulse_o => sig_pulse
);
-- Transfer last frequency measure from sig_i to clk_i -- Transfer last frequency measure from sig_i to clk_i
cmp_gc_sync_word_wr : entity work.gc_sync_word_wr cmp_gc_sync_word_wr_freq : entity work.gc_sync_word_wr
generic map ( generic map (
g_AUTO_WR => TRUE, g_AUTO_WR => False,
g_WIDTH => 32) g_WIDTH => 32)
port map ( port map (
clk_in_i => sig_i, clk_in_i => sig_i,
rst_in_n_i => '1', rst_in_n_i => enable_sig,
clk_out_i => clk_i, clk_out_i => clk_i,
rst_out_n_i => rst_n_i, rst_out_n_i => rst_n_i,
wr_i => gate_pulse_synced_d,
data_i => freq_reg, data_i => freq_reg,
data_o => freq_o, data_o => freq_o,
wr_o => freq_wr); wr_o => freq_wr);
cmp_gc_sync_word_wr_counter : entity work.gc_sync_word_wr
generic map (
g_AUTO_WR => True,
g_WIDTH => 32)
port map (
clk_in_i => sig_i,
rst_in_n_i => enable_sig,
clk_out_i => clk_i,
rst_out_n_i => rst_n_i,
data_i => std_logic_vector(counter),
data_o => counter_resync,
wr_o => counter_wr);
process (clk_i) process (clk_i)
begin begin
if rising_edge (clk_i) then if rising_edge (clk_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
generation <= (others => '0'); generation <= (others => '0');
counter <= (others => '0'); counter_o <= (others => '0');
else else
if freq_wr = '1' then if freq_wr = '1' then
generation <= generation + 1; generation <= generation + 1;
end if; end if;
if sig_pulse = '1' then if counter_wr = '1' then
counter <= counter + 1; counter_o <= counter_resync;
end if; end if;
end if; end if;
end if; end if;
end process; end process;
counter_o <= std_logic_vector (counter);
generation_o <= std_logic_vector (generation); generation_o <= std_logic_vector (generation);
end arch; end arch;
...@@ -22,6 +22,14 @@ memory-map: ...@@ -22,6 +22,14 @@ memory-map:
width: 16 width: 16
access: rw access: rw
children: children:
- field:
name: enable
comment: Enable the unit
description: >
Set to one to enable the unit. When set to zero, the unit
is reset. The input signal must be active for at least
3 cycles before the signal has an effect.
range: 4
- field: - field:
name: window name: window
description: Period used to compute frequency description: Period used to compute frequency
...@@ -29,8 +37,9 @@ memory-map: ...@@ -29,8 +37,9 @@ memory-map:
Select the window to measure the frequency. A change to this Select the window to measure the frequency. A change to this
value is taken into account at the end of the current value is taken into account at the end of the current
window. window.
00: 500us; 01: 50ms; 10: 5s; 11: 20s 000: 5us; 010: 500us; 100: 50ms; 101: 5s; 110: 20s
range: 1-0 001, 011, 111: unused.
range: 2-0
- reg: - reg:
name: generation name: generation
description: Result number description: Result number
......
-- Do not edit. Generated on Thu Mar 26 14:20:33 2020 by tgingold -- Do not edit. Generated on Mon May 04 16:51:42 2020 by gingold
-- With Cheby 1.4.dev0 and these options: -- With Cheby 1.4.dev0 and these options:
-- -i wr2rf_init_rf_regs.cheby --gen-hdl wr2rf_init_rf_regs.vhd -- -i wr2rf_init_rf_regs.cheby --gen-hdl wr2rf_init_rf_regs.vhd
......
-- Do not edit. Generated on Thu Mar 26 14:20:33 2020 by tgingold -- Do not edit. Generated on Mon May 04 16:51:42 2020 by gingold
-- With Cheby 1.4.dev0 and these options: -- With Cheby 1.4.dev0 and these options:
-- -i wr2rf_rftrigger_regs.cheby --gen-hdl wr2rf_rftrigger_regs.vhd -- -i wr2rf_rftrigger_regs.cheby --gen-hdl wr2rf_rftrigger_regs.vhd
...@@ -24,8 +24,10 @@ entity wr2rf_rftrigger_regs is ...@@ -24,8 +24,10 @@ entity wr2rf_rftrigger_regs is
t2_o : out t_wishbone_master_out; t2_o : out t_wishbone_master_out;
-- Control register -- Control register
-- Select the window to measure the frequency. A change to this value is taken into account at the end of the current window. 00: 500us; 01: 50ms; 10: 5s; 11: 20s -- Enable the unit
rf_diag_control_window_o : out std_logic_vector(1 downto 0); rf_diag_control_enable_o : out std_logic;
-- Select the window to measure the frequency. A change to this value is taken into account at the end of the current window. 000: 5us; 010: 500us; 100: 50ms; 101: 5s; 110: 20s 001, 011, 111: unused.
rf_diag_control_window_o : out std_logic_vector(2 downto 0);
-- This register is incremented at the end of the window, when the new frequency is made available. -- This register is incremented at the end of the window, when the new frequency is made available.
rf_diag_generation_i : in std_logic_vector(15 downto 0); rf_diag_generation_i : in std_logic_vector(15 downto 0);
...@@ -62,7 +64,8 @@ architecture syn of wr2rf_rftrigger_regs is ...@@ -62,7 +64,8 @@ architecture syn of wr2rf_rftrigger_regs is
signal t2_tr : std_logic; signal t2_tr : std_logic;
signal t2_wack : std_logic; signal t2_wack : std_logic;
signal t2_rack : std_logic; signal t2_rack : std_logic;
signal rf_diag_control_window_reg : std_logic_vector(1 downto 0); signal rf_diag_control_enable_reg : std_logic;
signal rf_diag_control_window_reg : std_logic_vector(2 downto 0);
signal rf_diag_control_wreq : std_logic; signal rf_diag_control_wreq : std_logic;
signal rf_diag_control_wack : std_logic; signal rf_diag_control_wack : std_logic;
signal rd_ack_d0 : std_logic; signal rd_ack_d0 : std_logic;
...@@ -167,15 +170,18 @@ begin ...@@ -167,15 +170,18 @@ begin
t2_o.dat(15 downto 0) <= wr_dat_d0; t2_o.dat(15 downto 0) <= wr_dat_d0;
-- Register rf_diag_control -- Register rf_diag_control
rf_diag_control_enable_o <= rf_diag_control_enable_reg;
rf_diag_control_window_o <= rf_diag_control_window_reg; rf_diag_control_window_o <= rf_diag_control_window_reg;
process (clk_i) begin process (clk_i) begin
if rising_edge(clk_i) then if rising_edge(clk_i) then
if rst_n_i = '0' then if rst_n_i = '0' then
rf_diag_control_window_reg <= "00"; rf_diag_control_enable_reg <= '0';
rf_diag_control_window_reg <= "000";
rf_diag_control_wack <= '0'; rf_diag_control_wack <= '0';
else else
if rf_diag_control_wreq = '1' then if rf_diag_control_wreq = '1' then
rf_diag_control_window_reg <= wr_dat_d0(1 downto 0); rf_diag_control_enable_reg <= wr_dat_d0(4);
rf_diag_control_window_reg <= wr_dat_d0(2 downto 0);
end if; end if;
rf_diag_control_wack <= rf_diag_control_wreq; rf_diag_control_wack <= rf_diag_control_wreq;
end if; end if;
...@@ -247,7 +253,7 @@ begin ...@@ -247,7 +253,7 @@ begin
end process; end process;
-- Process for read requests. -- Process for read requests.
process (adr_int, rd_req_int, t1_i.dat, t1_rack, t2_i.dat, t2_rack, rf_diag_control_window_reg, rf_diag_generation_i, rf_diag_freq_i, rf_diag_counter_i) begin process (adr_int, rd_req_int, t1_i.dat, t1_rack, t2_i.dat, t2_rack, rf_diag_control_window_reg, rf_diag_control_enable_reg, rf_diag_generation_i, rf_diag_freq_i, rf_diag_counter_i) begin
-- By default ack read requests -- By default ack read requests
rd_dat_d0 <= (others => 'X'); rd_dat_d0 <= (others => 'X');
t1_re <= '0'; t1_re <= '0';
...@@ -270,8 +276,10 @@ begin ...@@ -270,8 +276,10 @@ begin
when "0" => when "0" =>
-- Reg rf_diag_control -- Reg rf_diag_control
rd_ack_d0 <= rd_req_int; rd_ack_d0 <= rd_req_int;
rd_dat_d0(1 downto 0) <= rf_diag_control_window_reg; rd_dat_d0(2 downto 0) <= rf_diag_control_window_reg;
rd_dat_d0(15 downto 2) <= (others => '0'); rd_dat_d0(3) <= '0';
rd_dat_d0(4) <= rf_diag_control_enable_reg;
rd_dat_d0(15 downto 5) <= (others => '0');
when "1" => when "1" =>
-- Reg rf_diag_generation -- Reg rf_diag_generation
rd_ack_d0 <= rd_req_int; rd_ack_d0 <= rd_req_int;
......
-- Do not edit. Generated on Thu Mar 26 14:20:34 2020 by tgingold -- Do not edit. Generated on Mon May 04 16:51:42 2020 by gingold
-- With Cheby 1.4.dev0 and these options: -- With Cheby 1.4.dev0 and these options:
-- -i wr2rf_vme_regs.cheby --gen-hdl wr2rf_vme_regs.vhd -- -i wr2rf_vme_regs.cheby --gen-hdl wr2rf_vme_regs.vhd
......
...@@ -15,8 +15,8 @@ architecture arch of tb_vtu is ...@@ -15,8 +15,8 @@ architecture arch of tb_vtu is
signal clk_sys : std_logic := '0'; signal clk_sys : std_logic := '0';
signal rst_sys : std_logic; signal rst_sys : std_logic;
signal clk_rf : std_logic := '0'; signal clk_rf : std_logic := '1';
signal clk_vtu : std_logic := '0'; signal clk_vtu : std_logic := '1';
signal sync : std_logic := '0'; signal sync : std_logic := '0';
signal trig_p : std_logic := '0'; signal trig_p : std_logic := '0';
...@@ -86,7 +86,7 @@ begin ...@@ -86,7 +86,7 @@ begin
-- RF clock, ~200Mhz (5ns) -- RF clock, ~200Mhz (5ns)
-- VTU clock, ~25Mhz (40ns) -- VTU clock, ~25Mhz (40ns)
process process
variable cnt : natural := 8; variable cnt : natural := 1;
begin begin
clk_rf <= not clk_rf; clk_rf <= not clk_rf;
if cnt = 8 then if cnt = 8 then
...@@ -231,6 +231,34 @@ begin ...@@ -231,6 +231,34 @@ begin
-- assert s (TRIGUNIT_REGS_STATUS_WRONGWVALUE_OFFSET) = '0' severity error; -- assert s (TRIGUNIT_REGS_STATUS_WRONGWVALUE_OFFSET) = '0' severity error;
end read_status; end read_status;
procedure read_diag (freq : out natural)
is
variable val, val2, gen : std_logic_vector(15 downto 0);
begin
report "show vtu";
wait until rising_edge (clk_sys);
read16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_GENERATION, gen);
report "Vtu: generation: " & to_string(gen);
read16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_FREQ, val);
read16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_FREQ + 2, val2);
freq := to_integer(unsigned(val) & unsigned(val2));
report "Vtu: freq: " & natural'image(freq);
read16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_COUNTER, val);
read16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_COUNTER + 2, val2);
report "Vtu: counter: " & natural'image(to_integer(unsigned(val) & unsigned(val2)));
read16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_GENERATION, val);
report "Vtu: generation: " & to_string(val);
assert gen = val report "mismatching generation, values are not valid" severity error;
end read_diag;
procedure show_diag
is
variable freq : natural;
begin
report "show vtu";
read_diag (freq);
end show_diag;
procedure test_window (bval : natural; hval : natural; wval : natural) procedure test_window (bval : natural; hval : natural; wval : natural)
is is
variable val : std_logic_vector(15 downto 0); variable val : std_logic_vector(15 downto 0);
...@@ -393,10 +421,16 @@ begin ...@@ -393,10 +421,16 @@ begin
variable val : std_logic_vector(15 downto 0); variable val : std_logic_vector(15 downto 0);
variable cnt : natural; variable cnt : natural;
variable dly_exp : natural; variable dly_exp : natural;
variable freq : natural;
begin begin
report "test highfreq - setup vtu ht:" & natural'image(htval); report "test highfreq - setup vtu ht:" & natural'image(htval);
-- Program the vtu
wait until rising_edge(clk_sys); wait until rising_edge(clk_sys);
-- Reset the diag unit
write16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_CONTROL, x"0000");
-- Program the vtu
-- Delay between start and the first pulse. -- Delay between start and the first pulse.
write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_BVALUEOFFLINE, write64be_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_BVALUEOFFLINE,
std_logic_vector(to_unsigned(bval, 64))); std_logic_vector(to_unsigned(bval, 64)));
...@@ -426,8 +460,19 @@ begin ...@@ -426,8 +460,19 @@ begin
assert val (TRIGUNIT_REGS_STATUS_STARTREADY_OFFSET) = '1' severity error; assert val (TRIGUNIT_REGS_STATUS_STARTREADY_OFFSET) = '1' severity error;
assert val (TRIGUNIT_REGS_STATUS_RUNNING_OFFSET) = '1' severity error; assert val (TRIGUNIT_REGS_STATUS_RUNNING_OFFSET) = '1' severity error;
-- Wait until end of generation. -- Wait until the first pulse.
wait on observer_state; wait until rising_edge(trig_p);
wait until rising_edge(clk_sys);
wait until rising_edge(clk_sys);
-- Enable the diag unit (5us)
write16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_CONTROL, x"0010");
-- Wait for a full diag unit cycle.
wait for 5 us;
-- Wait a little bit more to be after the generation.
wait for 200 ns;
-- Check observer status. -- Check observer status.
assert observer_state = OBS_DONE severity error; assert observer_state = OBS_DONE severity error;
assert observer_period = htval * 5 ns; assert observer_period = htval * 5 ns;
...@@ -443,6 +488,9 @@ begin ...@@ -443,6 +488,9 @@ begin
wait for 40 ns; wait for 40 ns;
stop <= '0'; stop <= '0';
read_diag (freq);
report "expected freq: " & natural'image(200_000_000 / 200_000 / htval);
-- Wait a little bit (2 full periods) -- Wait a little bit (2 full periods)
wait for 2 * 2 * observer_period; wait for 2 * 2 * observer_period;
...@@ -461,11 +509,13 @@ begin ...@@ -461,11 +509,13 @@ begin
wait until rst_sys = '0'; wait until rst_sys = '0';
-- Program the diag (500us) -- Program the diag (5us) + enable.
write16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_CONTROL, x"0000"); write16_pl (clk_sys, wb_in, wb_out, ADDR_TRIGUNIT_REGS_TRIGDIAG + ADDR_VTUDIAG_REGS_CONTROL, x"0010");
test_window (25, 13, 7); test_window (25, 13, 7);
show_diag;
------------------------------------------------------------------------------------------------- -------------------------------------------------------------------------------------------------
-- Test 2: check that missing valid parameters is reported. -- Test 2: check that missing valid parameters is reported.
......
package vtudiag_regs_Consts is package vtudiag_regs_Consts is
constant VTUDIAG_REGS_SIZE : Natural := 16; constant VTUDIAG_REGS_SIZE : Natural := 16;
constant ADDR_VTUDIAG_REGS_CONTROL : Natural := 16#0#; constant ADDR_VTUDIAG_REGS_CONTROL : Natural := 16#0#;
constant VTUDIAG_REGS_CONTROL_ENABLE_OFFSET : Natural := 4;
constant VTUDIAG_REGS_CONTROL_WINDOW_OFFSET : Natural := 0; constant VTUDIAG_REGS_CONTROL_WINDOW_OFFSET : Natural := 0;
constant ADDR_VTUDIAG_REGS_GENERATION : Natural := 16#2#; constant ADDR_VTUDIAG_REGS_GENERATION : Natural := 16#2#;
constant ADDR_VTUDIAG_REGS_FREQ : Natural := 16#4#; constant ADDR_VTUDIAG_REGS_FREQ : Natural := 16#4#;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment