Commit cce8e778 authored by Denia Bouhired-Ferrag's avatar Denia Bouhired-Ferrag

Modified top files to support all modifications in register map plus the new…

Modified top files to support all modifications in register map plus the new burst controller. Note that the burst controller supported in this commit is the one that averages frequency over 1000 pulses
parent 0161ea17
general-cores @ 9a40120b
Subproject commit 382b46c19757e0c7c8574ebe56f32169c5a84b20
Subproject commit 9a40120ba4af4a7551f9fd8cbbe61f1d434f30bf
--==============================================================================
-- CERN (BE-CO-HT)
-- Burst mode control module
--==============================================================================
--
-- author: Denia Bouhired (denia.bouhired@cern.ch)
--
-- Date of creation: 19-09-2016
--
-- version: 1.0
--
-- description:
-- This module serves as a burst mode controller. When pulses of pre-defined length (250 ns) arrive, this module evaluates whether the module needs some "cool-off" time every burst_length number of pulses. Burst-length is the maximum number of pulses the board can handle at maximum frequency 2MHz and is determined through direct laboratory measurements on board prototypes. It is considered a pure hardware limitation. For version 1 this is set to absolute maximum of 1000 but the generic value can be changed for lower values.
-- dependencies:
--
--==============================================================================
-- GNU LESSER GENERAL PUBLIC LICENSE
--==============================================================================
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--==============================================================================
-- last changes:
-- 19-09-2016 Denia Bouhired File created.
--
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
-- use work.gencores_pkg.all;
-- use work.wishbone_pkg.all;
use work.conv_common_gw_pkg.all;
entity conv_burst_ctrl is
generic
(
-- Short pulse width, in number of clk_i cycles
-- Default short pulse width (20 MHz clock): 250 ns = 5 clk cycles
g_pwidth : natural range 2 to 40 := 5;
-- Duty cycle divider: D = 1/g_duty_cycle_div
g_duty_cycle_div : natural := 200;
-- Number of pulses allowed before decision is made on whether to continue burst
-- Maximum number of pulses that can be received at the worst case 2MHz scenario
g_max_burst_len : natural := 1000; -- Check every "g_eval_burst_len" pulses
-- Burst is evaluated after g_max_burst_len or after a timeout g_burst_timeout set to 1 s.
--g_cnt_size : natural := 32;
g_burst_timeout : natural := 200000 -- 20000000 corresponds to 1 second timeout
-- 60000 corresponds to 3ms timeout
);
port
(
-- Clock and active-low reset inputs
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Enable input, pulse generation is enabled when '1'
en_i : in std_logic;
pulse_burst_i : in std_logic;
pulse_burst_o : out std_logic;
-- Burst error output, pulses high for one clock cycle when a pulse arrives
-- within a burst rejection phase
burst_err_p_o : out std_logic
);
end entity conv_burst_ctrl;
architecture behav of conv_burst_ctrl is
--============================================================================
-- Type declarations
--============================================================================
type t_state is (
IDLE, --Idle state wait for pulse to arrive
GEN_PULSE_ON, --Continue generating pulses and counting them
GEN_PULSE_OFF, --And count pulse OFF time
REJ_PULSE --Reject pulses and start cool-off period
);
--============================================================================
-- Constant declarations
--============================================================================
-- This bit can be done by adding second counter to count pulse on time
constant c_average_pulse_off : natural := (g_duty_cycle_div)*g_pwidth; -- 250 ns * (200)
constant c_max_burst_rej : natural := g_max_burst_len*c_average_pulse_off; -- (250ns * (200)) *1000
--============================================================================
-- Function and procedure declarations
--============================================================================
--============================================================================
-- Signal declarations
--============================================================================
signal burst_ctrl_rst : std_logic;
-- Pulse burst trigger
signal pulse_train_in : std_logic;
--signal pulse_redge_p : std_logic;
--signal pulse_burst_sf : std_logic;
-- Pulse, pulse ON/OFF, burst length counters
signal pulse_cnt : unsigned(31 downto 0); -- Pulse counter
---signal cumul_pulse_on_c : unsigned(g_cnt_size-1 downto 0); -- Cumulative PULSE ON counter
---signal cumul_pulse_off_c : unsigned(g_cnt_size-1 downto 0); -- Cumulative PULSE OFF counter
signal cumul_burst_time : unsigned(31 downto 0); -- Cumulative burst time (ON and OFF)
signal burst_rq_off_c : unsigned(31 downto 0); -- Required rejection time for current burst
-- Flag new pulse
signal new_pulse : boolean;
--Flag burst rejection
--signal rej_active : boolean;
-- FSM signal
signal state : t_state;
signal nxt_state : t_state;
signal pulse_train_in_d0 : std_logic;
signal pulse_train_in_r_edge_p : std_logic;
--==============================================================================
-- architecture begin
--==============================================================================
begin
-- Generate the pulse on rising edge of pulse_burst_i
p_pulse_redge: process (burst_ctrl_rst, pulse_burst_i, en_i)
begin
if (burst_ctrl_rst = '1') then
pulse_train_in <= '0';
else
-- if (en_i = '1') then
pulse_train_in <= pulse_burst_i;
-- end if;
end if;
end process p_pulse_redge;
p_pulse_redge_detect : process (clk_i) is
begin
if rising_edge(clk_i) then
if (rst_n_i = '0') then
pulse_train_in_d0 <= '0';
pulse_train_in_r_edge_p <= '0';
else
pulse_train_in_d0 <= pulse_burst_i;
pulse_train_in_r_edge_p <= pulse_burst_i and (not pulse_train_in_d0);
end if;
end if;
end process p_pulse_redge_detect;
-- Synchronize the trigger in clk_i domain
-- cmp_sync_ffs : gc_sync_ffs
-- generic map
-- (
-- g_sync_edge => "positive"
-- )
-- port map
-- (
-- clk_i => clk_i,
-- rst_n_i => rst_n_i,
-- data_i => pulse_burst,
-- ppulse_o => pulse_redge_p
-- );
--pulse_redge_p <= pulse_burst;
-- process (clk_i)
-- begin
-- if rising_edge(clk_i) then
pulse_burst_o <= pulse_train_in;
-- end if;
-- end process;
--============================================================================
-- Burst length adjustment logic
--============================================================================
--Synchronous procees to define state conditions
p_fsm_transitions: process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
state <= IDLE;
elsif (en_i = '1') then
state <= nxt_state;
end if;
end if;
end process;
-- FSM States
p_FSM_states: process(state, pulse_train_in, cumul_burst_time, pulse_cnt, burst_rq_off_c)
begin
case state is
---------------------------------------------------------------------
-- IDLE
---------------------------------------------------------------------
-- Clear all values and go to pulse generation state when the
-- appropriate input arrives
---------------------------------------------------------------------
when IDLE =>
if (pulse_train_in = '1') then
nxt_state <= GEN_PULSE_ON;
else
nxt_state <= state;
end if;
---------------------------------------------------------------------
-- GEN_PULSE_ON
---------------------------------------------------------------------
-- When a new pulse arrives increment the pulse ON cycle counter and the pulse ON counter
-- Got to GEN_PULSE_OFF state when the pulse is OFF
---------------------------------------------------------------------
when GEN_PULSE_ON =>
if (pulse_train_in = '1') then
nxt_state <= state;
else
nxt_state <= GEN_PULSE_OFF;
end if;
---------------------------------------------------------------------
-- GEN_PULSE_OFF
---------------------------------------------------------------------
-- Count the number of cycles of pulse OFF
-- Go to GEN_PULSE_ON state when new pulse arrives
-- If the maximum number of pulses per burst is reached, go to REJ_PULSE state
-- If the the burst time out is reached got to TIMEOUT state
---------------------------------------------------------------------
when GEN_PULSE_OFF =>
-- If maximum number of consecutive pulses is reached start rejection phase
if (pulse_cnt = g_max_burst_len or cumul_burst_time >= g_burst_timeout) then
if (cumul_burst_time < burst_rq_off_c) then
nxt_state <= REJ_PULSE;
else
nxt_state <= IDLE;
end if;
elsif (pulse_train_in = '1' ) then
nxt_state <= GEN_PULSE_ON;
end if;
---------------------------------------------------------------------
-- REJ_PULSE
---------------------------------------------------------------------
-- Start pulse rejection until c_max_burst_rej time is reached
-- the go back to IDLE state
---------------------------------------------------------------------
when REJ_PULSE =>
if (cumul_burst_time >= burst_rq_off_c) then
nxt_state <= IDLE;
else
nxt_state <= state;
end if;
when others =>
nxt_state <= IDLE;
end case;
end process p_FSM_states;
-- FSM Outputs
p_FSM_outputs: process(clk_i)
begin
if rising_edge (clk_i) then
case state is
---------------------------------------------------------------------
-- IDLE
---------------------------------------------------------------------
-- Clear all values and go to pulse generation state when the
-- appropriate input arrives
---------------------------------------------------------------------
when IDLE =>
pulse_cnt <= (others => '0');
cumul_burst_time <= (others => '0');
burst_rq_off_c <= (others => '0');
burst_ctrl_rst <= '0';
new_pulse <= false;
--rej_active <= false;
if (pulse_train_in = '1') then
cumul_burst_time <= cumul_burst_time + 1;
new_pulse <= true;
end if;
---------------------------------------------------------------------
-- GEN_PULSE_ON
---------------------------------------------------------------------
-- When a new pulse arrives increment the pulse ON cycle counter and the pulse ON counter
-- Got to GEN_PULSE_OFF state when the pulse is OFF
---------------------------------------------------------------------
when GEN_PULSE_ON =>
cumul_burst_time <= cumul_burst_time + 1;
if (new_pulse) then -- count only new pulses, once
pulse_cnt <= pulse_cnt + 1;
new_pulse <= false; -- A new pulse has already been counted
burst_rq_off_c <= burst_rq_off_c + c_average_pulse_off;
end if;
---------------------------------------------------------------------
-- GEN_PULSE_OFF
---------------------------------------------------------------------
-- Count the number of cycles of pulse OFF
-- Go to GEN_PULSE_ON state when new pulse arrives
-- If the maximum number of pulses per burst is reached, go to REJ_PULSE state
-- If the the burst time out is reached got to TIMEOUT state
---------------------------------------------------------------------
when GEN_PULSE_OFF =>
cumul_burst_time <= cumul_burst_time + 1;
-- If maximum number of consecutive pulses is reached start rejection phase
if (pulse_cnt = g_max_burst_len or cumul_burst_time >= g_burst_timeout) then
if (cumul_burst_time < burst_rq_off_c) then
burst_ctrl_rst <= '1';
end if;
elsif (pulse_train_in = '1' ) then
new_pulse <= true;
end if;
---------------------------------------------------------------------
-- REJ_PULSE
---------------------------------------------------------------------
-- Start pulse rejection until c_max_burst_rej time is reached
-- the go back to IDLE state
---------------------------------------------------------------------
when REJ_PULSE =>
if (cumul_burst_time >= burst_rq_off_c) then
burst_ctrl_rst <= '0';
else
cumul_burst_time <= cumul_burst_time + 1;
end if;
-- Error pulse is generated for one clock cycle each time a pulse arrives during rejection mode
burst_err_p_o <= '0';
if pulse_train_in_r_edge_p = '1' then
burst_err_p_o <= '1';
end if;
end case;
end if;
end process p_FSM_outputs;
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
--==============================================================================
-- CERN (BE-CO-HT)
-- Burst mode control module
--==============================================================================
--
-- author: Denia Bouhired (denia.bouhired@cern.ch)
--
-- Date of creation: 19-09-2016
--
-- version: 1.0
--
-- description:
-- This module serves as a burst mode controller. When pulses of pre-defined length (250 ns) arrive, this module evaluates whether the module needs some "cool-off" time every burst_length number of pulses. Burst-length is the maximum number of pulses the board can handle at maximum frequency 2MHz and is determined through direct laboratory measurements on board prototypes. It is considered a pure hardware limitation. For version 1 this is set to absolute maximum of 1000 but the generic value can be changed for lower values.
-- dependencies:
--
--==============================================================================
-- GNU LESSER GENERAL PUBLIC LICENSE
--==============================================================================
-- This source file is free software; you can redistribute it and/or modify it
-- under the terms of the GNU Lesser General Public License as published by the
-- Free Software Foundation; either version 2.1 of the License, or (at your
-- option) any later version. This source is distributed in the hope that it
-- will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-- of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-- See the GNU Lesser General Public License for more details. You should have
-- received a copy of the GNU Lesser General Public License along with this
-- source; if not, download it from http://www.gnu.org/licenses/lgpl-2.1.html
--==============================================================================
-- last changes:
-- 19-09-2016 Denia Bouhired File created.
--
--==============================================================================
-- TODO: -
--==============================================================================
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.gencores_pkg.all;
use work.wishbone_pkg.all;
use work.conv_common_gw_pkg.all;
entity conv_burst_ctrl is
generic
(
-- Short pulse width, in number of clk_i cycles
-- Default short pulse width (20 MHz clock): 250 ns = 5 clk cycles
g_pwidth : natural range 2 to 40 := 5;
-- Duty cycle divider: D = 1/g_duty_cycle_div
g_duty_cycle_div : natural := 200;
-- Number of pulses allowed before decision is made on whether to continue burst
-- Maximum number of pulses that can be received at the worst case 2MHz scenario
g_max_burst_len : natural := 1000; -- Check every "g_eval_burst_len" pulses
-- Burst is evaluated after g_max_burst_len or after a timeout g_burst_timeout set to 1 s.
--g_cnt_size : natural := 32;
g_burst_timeout : natural := 200000 -- 20000000 corresponds to 1 second timeout
-- 60000 corresponds to 3ms timeout
);
port
(
-- Clock and active-low reset inputs
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Enable input, pulse generation is enabled when '1'
en_i : in std_logic;
pulse_burst_i : in std_logic;
pulse_burst_o : out std_logic;
-- Burst error output, pulses high for one clock cycle when a pulse arrives
-- within a burst rejection phase
burst_err_p_o : out std_logic
);
end entity conv_burst_ctrl;
architecture behav of conv_burst_ctrl is
--============================================================================
-- Type declarations
--============================================================================
type t_state is (
IDLE, --Idle state wait for pulse to arrive
GEN_PULSE_ON, --Continue generating pulses and counting them
GEN_PULSE_OFF, --And count pulse OFF time
REJ_PULSE --Reject pulses and start cool-off period
);
--============================================================================
-- Constant declarations
--============================================================================
-- This bit can be done by adding second counter to count pulse on time
constant c_average_pulse_off : natural := (g_duty_cycle_div)*g_pwidth; -- 250 ns * (200)
constant c_max_burst_rej : natural := g_max_burst_len*c_average_pulse_off; -- (250ns * (200)) *1000
--============================================================================
-- Function and procedure declarations
--============================================================================
--============================================================================
-- Signal declarations
--============================================================================
signal burst_ctrl_rst : std_logic;
-- Pulse burst trigger
signal pulse_train_in : std_logic;
--signal pulse_redge_p : std_logic;
--signal pulse_burst_sf : std_logic;
-- Pulse, pulse ON/OFF, burst length counters
signal pulse_cnt : unsigned(31 downto 0); -- Pulse counter
---signal cumul_pulse_on_c : unsigned(g_cnt_size-1 downto 0); -- Cumulative PULSE ON counter
---signal cumul_pulse_off_c : unsigned(g_cnt_size-1 downto 0); -- Cumulative PULSE OFF counter
signal cumul_burst_time : unsigned(31 downto 0); -- Cumulative burst time (ON and OFF)
signal burst_rq_off_c : unsigned(31 downto 0); -- Required rejection time for current burst
-- Flag new pulse
signal new_pulse : boolean;
--Flag burst rejection
signal rej_active : boolean;
-- FSM signal
signal state : t_state;
--==============================================================================
-- architecture begin
--==============================================================================
begin
-- Generate the pulse on rising edge of pulse_burst_i
p_pulse_redge: process(burst_ctrl_rst, pulse_burst_i)
begin
if (burst_ctrl_rst = '1') then
pulse_train_in <= '0';
elsif rising_edge(pulse_burst_i) then
if (en_i = '1' and not rej_active) then
pulse_train_in <= pulse_burst_i;
burst_err_p_o <= '0';
else
pulse_train_in <= '0';
burst_err_p_o <= '1';
end if;
else
pulse_train_in <= '0';
burst_err_p_o <= '0';
end if;
end process p_pulse_redge;
-- Synchronize the trigger in clk_i domain
-- cmp_sync_ffs : gc_sync_ffs
-- generic map
-- (
-- g_sync_edge => "positive"
-- )
-- port map
-- (
-- clk_i => clk_i,
-- rst_n_i => rst_n_i,
-- data_i => pulse_burst,
-- ppulse_o => pulse_redge_p
-- );
--pulse_redge_p <= pulse_burst;
process (clk_i)
begin
if rising_edge(clk_i) then
pulse_burst_o <= pulse_train_in;
end if;
end process;
--============================================================================
-- Burst length adjustment logic
--============================================================================
-- Generate FSM logic
p_burst_length: process(clk_i)
begin
if rising_edge (clk_i) then -- ***CHECK WHAT ELSE NEEDS TO BE RESET
if (rst_n_i = '0') then
state <= IDLE;
burst_ctrl_rst <= '1';
--pulse_burst_sf <= '0';
pulse_cnt <= (others => '0');
---cumul_pulse_on_c <= (others => '0');
---cumul_pulse_off_c <= (others => '0');
cumul_burst_time <= (others => '0');
burst_rq_off_c <= (others => '0');
new_pulse <= false;
rej_active <= false;
--burst_err_p_o <= '0';
elsif (en_i = '1') then
--pulse_burst_sf <= pulse_burst;
case state is
---------------------------------------------------------------------
-- IDLE
---------------------------------------------------------------------
-- Clear all values and go to pulse generation state when the
-- appropriate input arrives
---------------------------------------------------------------------
when IDLE =>
--pulse_burst_sf <= pulse_burst;
pulse_cnt <= (others => '0');
---cumul_pulse_on_c <= (others => '0');
---cumul_pulse_off_c <= (others => '0');
cumul_burst_time <= (others => '0');
burst_rq_off_c <= (others => '0');
burst_ctrl_rst <= '0';
rej_active <= false;
if (pulse_train_in = '1') then
new_pulse <= true;
state <= GEN_PULSE_ON;
---cumul_pulse_on_c <= cumul_pulse_on_c + 1;
cumul_burst_time <= cumul_burst_time + 1;
end if;
---------------------------------------------------------------------
-- GEN_PULSE_ON
---------------------------------------------------------------------
-- When a new pulse arrives increment the pulse ON cycle counter and the pulse ON counter
-- Got to GEN_PULSE_OFF state when the pulse is OFF
---------------------------------------------------------------------
when GEN_PULSE_ON =>
----cumul_burst_time <= cumul_pulse_on_c + cumul_pulse_off_c + 1;
cumul_burst_time <= cumul_burst_time + 1;
if (pulse_train_in = '1') then
---cumul_pulse_on_c <= cumul_pulse_on_c + 1;
if (new_pulse) then -- count only new pulses, once
pulse_cnt <= pulse_cnt + 1;
new_pulse <= false; -- A new pulse has already been counted
burst_rq_off_c <= burst_rq_off_c + c_average_pulse_off;
end if;
else
state <= GEN_PULSE_OFF;
---cumul_pulse_off_c <= cumul_pulse_off_c + 1;
end if;
---------------------------------------------------------------------
-- GEN_PULSE_OFF
---------------------------------------------------------------------
-- Count the number of cycles of pulse OFF
-- Go to GEN_PULSE_ON state when new pulse arrives
-- If the maximum number of pulses per burst is reached, go to REJ_PULSE state
-- If the the burst time out is reached got to TIMEOUT state
---------------------------------------------------------------------
when GEN_PULSE_OFF =>
----cumul_burst_time <= cumul_pulse_on_c + cumul_pulse_off_c + 1;
cumul_burst_time <= cumul_burst_time + 1;
if (pulse_train_in = '1' ) then
new_pulse <= true; --waiting for new pulse
state <= GEN_PULSE_ON;
---cumul_pulse_on_c <= cumul_pulse_on_c + 1;
-- If maximum number of consecutive pulses is reached start rejection phase
elsif (pulse_cnt = g_max_burst_len or cumul_burst_time >= g_burst_timeout) then
if (cumul_burst_time < burst_rq_off_c) then
rej_active <= true;
state <= REJ_PULSE;
end if;
else
---cumul_pulse_off_c <= cumul_pulse_off_c + 1;
end if;
---------------------------------------------------------------------
-- REJ_PULSE
---------------------------------------------------------------------
-- Start pulse rejection until c_max_burst_rej time is reached
-- the go back to IDLE state
---------------------------------------------------------------------
when REJ_PULSE =>
if (cumul_burst_time >= burst_rq_off_c) then
rej_active <= false;
state <= IDLE;
else
cumul_burst_time <= cumul_burst_time + 1;
end if;
when others =>
state <= IDLE;
end case;
end if;
end if;
end process p_burst_length;
end architecture behav;
--==============================================================================
-- architecture end
--==============================================================================
......@@ -77,13 +77,21 @@ entity conv_common_gw is
-- Generate pulse repetition logic with fixed output pulse width
g_pgen_fixed_width : boolean;
-- Pulse width at pulse generator output (valid with fixed output pulse width)
g_pgen_pwidth : natural range 20 to 40 := 24;
g_pgen_pwidth : natural range 2 to 40 := 24;
g_pgen_pwidth_sh : natural range 2 to 40 := 5;
-- Duty cycle divider ratio for pulse generator
-- output pulse will be limited to 1/g_pgen_duty_cycle_div
g_pgen_duty_cycle_div : natural := 5;
g_pgen_duty_cycle_div : natural range 10 to 300 := 200;
g_pgen_duty_cycle_div_sh : natural range 2 to 300 := 2;
-- Pulse generator glitch filter length in number of clk_20_i cycles
g_pgen_gf_len : integer := 4;
-- Burst-mode-specific generics:
-- Maximum number of pulses in burst before forced burst rejection. Number dictated by hardware limitations
g_burstctrl_max_burst_len : natural := 1000;
-- 20000000 corresponds to 1 second timeout, 60000 corresponds to 3ms timeout. When timeout is reached burst rejection may start if necessary else go back to IDLE. Useful when pulses are not frequent.
g_burstctrl_timeout : natural := 200000;
-- Generate logic with pulse counters
g_with_pulse_cnt : boolean := false;
......@@ -112,7 +120,10 @@ entity conv_common_gw is
rst_n_o : out std_logic;
-- Glitch filter active-low enable signal
gf_en_n_i : in std_logic;
gf_en_n_i : in std_logic;
-- Burst mode or short pulse mode enable signal
burst_en_n_i : in std_logic;
-- Channel enable
global_ch_oen_o : out std_logic;
......@@ -219,6 +230,12 @@ architecture arch of conv_common_gw is
--============================================================================
-- Constant declarations
--============================================================================
-- Short pulse widths
constant c_pgen_pwidth_sh : natural := 5;
-- Burst mode maximum duty cycle is 50%, i.e. divider is 2
constant c_pgen_duty_cycle_div_sh : natural := 2;
-- Number of Wishbone masters and slaves, for wb_crossbar
constant c_nr_masters : natural := 1;
constant c_nr_slaves : natural := 3;
......@@ -234,6 +251,7 @@ architecture arch of conv_common_gw is
constant c_addr_onewire_mst : t_wishbone_address := x"00000200";
constant c_addr_sdb : t_wishbone_address := x"00000f00";
-- SDB interconnect layout
-- c_conv_regs_sdb defined in conv_common_gw_pkg.vhd
constant c_sdb_layout : t_sdb_record_array(c_nr_slaves-1 downto 0) := (
......@@ -249,7 +267,7 @@ architecture arch of conv_common_gw is
-- 1 -- WRPRES bit
-- xx -- channel mask for max. nr. channels
constant c_tagbuff_data_width : positive := 40 + 28 + 1 + c_max_nr_chans;
--============================================================================
-- Type declarations
--============================================================================
......@@ -290,7 +308,11 @@ architecture arch of conv_common_gw is
signal trig_chan_blo_redge_p : std_logic_vector(g_nr_chans-1 downto 0);
signal trig_man : std_logic_vector(g_nr_chans-1 downto 0);
signal trig_pgen : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_sh : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_250ns : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_1200ns : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_d0 : std_logic_vector(g_nr_chans-1 downto 0);
signal pulse_outp_redge_p : std_logic_vector(g_nr_chans-1 downto 0);
signal inv_pulse_outp : std_logic_vector(g_nr_inv_chans-1 downto 0);
......@@ -400,6 +422,15 @@ architecture arch of conv_common_gw is
-- One-wire master signals
signal owr_en : std_logic_vector(0 downto 0);
signal owr_in : std_logic_vector(0 downto 0);
signal pps_is_zero : std_logic;
signal tmp_id : std_logic_vector(63 downto 0);
signal tmp_temper : std_logic_vector(15 downto 0);
signal onewire_read_p : std_logic;
signal pps_load_p : std_logic;
signal id : std_logic_vector(63 downto 0);
signal temper : std_logic_vector(15 downto 0);
--==============================================================================
-- architecture begin
......@@ -624,8 +655,11 @@ end generate gen_pulse_cnt;
-- The trigger to the pulse generator is either manual OR from the channel input
trig_pgen(i) <= trig_chan(i) or trig_man(i);
-- Instantiate pulse generator block for the channel
cmp_pulse_gen : conv_pulse_gen
--sw_burst <= not burst_en_n_i;
-- Instantiate pulse generator block for the channel for normal continuous mode
cmp_pulse_gen_5 : conv_pulse_gen
generic map
(
g_with_fixed_pwidth => g_pgen_fixed_width,
......@@ -645,9 +679,66 @@ end generate gen_pulse_cnt;
pulse_err_p_o => pmisse_p(i),
pulse_o => pulse_outp(i)
pulse_o => pulse_outp_1200ns(i)
);
-------------------------------------------------------------------------------------
-- In burst mode, pulses are shorter, 250ns wide, and have a 50% duty cycle
-------------------------------------------------------------------------------------
--Instantiate pulse generator block for minimum pulse width and minimum allowed duty cycle
cmp_pulse_gen : conv_pulse_gen
generic map
(
g_with_fixed_pwidth => g_pgen_fixed_width,
g_pwidth => g_pgen_pwidth_sh,
g_duty_cycle_div => c_pgen_duty_cycle_div_sh
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
gf_en_n_i => gf_en_n_i,
en_i => '1',
trig_a_i => trig_pgen(i),
pulse_err_p_o => open, --pmisse_p(i),
pulse_o => pulse_outp_sh(i)
);
----------------------------------------------------------------------------------
-- Instantiate burst control block for the channel
cmp_burst_ctrl : conv_burst_ctrl
generic map
(
g_pwidth => c_pgen_pwidth_sh,
g_duty_cycle_div => g_pgen_duty_cycle_div,
g_max_burst_len => g_burstctrl_max_burst_len,
g_burst_timeout => g_burstctrl_timeout
)
port map
(
clk_i => clk_20_i,
rst_n_i => rst_20_n,
en_i => '1',
pulse_burst_i => pulse_outp_sh(i),
pulse_burst_o => pulse_outp_250ns(i),
burst_err_p_o => open
);
pulse_outp(i) <= pulse_outp_1200ns(i) when burst_en_n_i='1' else pulse_outp_250ns(i);
-----------------------------------------------------------------------------------
-- Process to flash pulse LED when a pulse is output
-- LED flash length: 26 ms
p_pulse_led : process (clk_20_i) is
......@@ -1295,7 +1386,12 @@ end generate gen_latest_timestamp_unused_chans;
reg_lsr_frontinvfs_i => line_inv_fs_i,
reg_lsr_rearfs_i => line_rear_fs,
reg_oswr_switches_i => sw_other_i
reg_mswr_switches_i => sw_other_i, --****
reg_oswr_switches_i => sw_other_i,
reg_ds18b20u_id_lsb_i => id (31 downto 0),
reg_ds18b20u_id_msb_i => id (63 downto 32),
reg_ds18b20u_temp_i => temper
);
--============================================================================
......@@ -1319,40 +1415,84 @@ end generate gen_latest_timestamp_unused_chans;
--============================================================================
-- The one-wire master component is used to control the on-board DS18B20
-- thermometer
cmp_onewire_master : wb_onewire_master
generic map
(
g_interface_mode => CLASSIC,
g_address_granularity => WORD,
g_num_ports => 1,
g_ow_btp_normal => "5.0",
g_ow_btp_overdrive => "1.0"
)
port map
(
clk_sys_i => clk_20_i,
rst_n_i => rst_20_n,
wb_cyc_i => xbar_master_out(c_slv_onewire_mst).cyc,
wb_sel_i => xbar_master_out(c_slv_onewire_mst).sel,
wb_stb_i => xbar_master_out(c_slv_onewire_mst).stb,
wb_we_i => xbar_master_out(c_slv_onewire_mst).we,
wb_adr_i => xbar_master_out(c_slv_onewire_mst).adr(4 downto 2),
wb_dat_i => xbar_master_out(c_slv_onewire_mst).dat,
wb_dat_o => xbar_master_in(c_slv_onewire_mst).dat,
wb_ack_o => xbar_master_in(c_slv_onewire_mst).ack,
wb_int_o => open,
wb_stall_o => xbar_master_in(c_slv_onewire_mst).stall,
owr_pwren_o => open,
owr_en_o => owr_en,
owr_i => owr_in
);
-- Generate tri-state buffer for thermometer
thermometer_b <= '0' when (owr_en(0) = '1') else
'Z';
owr_in(0) <= thermometer_b;
cmp_onewire: gc_ds182x_interface
generic map (freq => 20)
port map
(clk_i => clk_20_i,
rst_n_i => rst_20_n,
pps_p_i => pps_is_zero,
onewire_b => thermometer_b,
id_o => tmp_id,
temper_o => tmp_temper,
id_read_o => onewire_read_p,
id_ok_o => open
);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- pps generator based on the 100 MHz clk
cmp_pps_gen: wf_decr_counter
generic map(g_counter_lgth => 25)
port map
(uclk_i => clk_20_i,
counter_rst_i => rst_20_n,
counter_decr_i => '1',
counter_load_i => pps_load_p,
counter_top_i => "1001100010010110100000000", -- 20'000'000
counter_is_zero_o => pps_is_zero);
-- -- -- -- -- -- -- -- -- -- --
pps_load_p <= pps_is_zero; -- looping
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- registering of the read values
reg_reading: process(clk_20_i)
begin
if rising_edge(clk_20_i) then
temper <= (others => '0');
id <= (others => '0');
if(onewire_read_p = '1') then
temper <= tmp_temper;
id <= tmp_id;
end if;
end if;
end process;
-- cmp_onewire_master : wb_onewire_master
-- generic map
-- (
-- g_interface_mode => CLASSIC,
-- g_address_granularity => WORD,
-- g_num_ports => 1,
-- g_ow_btp_normal => "5.0",
-- g_ow_btp_overdrive => "1.0"
-- )
-- port map
-- (
-- clk_sys_i => clk_20_i,
-- rst_n_i => rst_20_n,
-- wb_cyc_i => xbar_master_out(c_slv_onewire_mst).cyc,
-- wb_sel_i => xbar_master_out(c_slv_onewire_mst).sel,
-- wb_stb_i => xbar_master_out(c_slv_onewire_mst).stb,
-- wb_we_i => xbar_master_out(c_slv_onewire_mst).we,
-- wb_adr_i => xbar_master_out(c_slv_onewire_mst).adr(4 downto 2),
-- wb_dat_i => xbar_master_out(c_slv_onewire_mst).dat,
-- wb_dat_o => xbar_master_in(c_slv_onewire_mst).dat,
-- wb_ack_o => xbar_master_in(c_slv_onewire_mst).ack,
-- wb_int_o => open,
-- wb_stall_o => xbar_master_in(c_slv_onewire_mst).stall,
-- owr_pwren_o => open,
-- owr_en_o => owr_en,
-- owr_i => owr_in
-- );
--Generate tri-state buffer for thermometer
-- thermometer_b <= '0' when (owr_en(0) = '1') else
-- 'Z';
-- owr_in(0) <= thermometer_b;
--============================================================================
-- Bicolor LED matrix logic
......
......@@ -53,6 +53,7 @@ package conv_common_gw_pkg is
-- _reimplement_ the conv_regs module
constant c_max_nr_chans : natural := 6;
--============================================================================
-- Component declarations
--============================================================================
......@@ -74,12 +75,18 @@ package conv_common_gw_pkg is
-- Generate pulse repetition logic with fixed output pulse width
g_pgen_fixed_width : boolean;
-- Pulse width at pulse generator output (valid with fixed output pulse width)
g_pgen_pwidth : natural range 20 to 40 := 24;
g_pgen_pwidth : natural range 2 to 40 := 24; --**DB: was 20 to 40
-- Duty cycle divider ratio for pulse generator
-- output pulse will be limited to 1/g_pgen_duty_cycle_div
g_pgen_duty_cycle_div : natural := 5;
g_pgen_duty_cycle_div : natural := 200;
-- Pulse generator glitch filter length in number of clk_20_i cycles
g_pgen_gf_len : integer := 4;
-- Burst-mode-specific generics:
-- Maximum number of pulses in burst before forced burst rejection. Number dictated by hardware limitations
g_burstctrl_max_burst_len : natural := 4;
-- 20000000 corresponds to 1 second timeout, 60000 corresponds to 3ms timeout. When timeout is reached burst rejection may start if necessary else go back to IDLE. Useful when pulses are not frequent.
g_burstctrl_timeout : natural := 200000;
-- Generate logic with pulse counters
g_with_pulse_cnt : boolean := false;
......@@ -110,6 +117,10 @@ package conv_common_gw_pkg is
-- Glitch filter active-low enable signal
gf_en_n_i : in std_logic;
-- Burst mode or short pulse mode enable signal
burst_en_n_i : in std_logic;
-- Channel enable
global_ch_oen_o : out std_logic;
......@@ -235,7 +246,7 @@ package conv_common_gw_pkg is
-- Default pulse width (20 MHz clock): 1.2 us
-- Minimum allowable pulse width (20 MHz clock): 1 us
-- Maximum allowable pulse width (20 MHz clock): 2 us
g_pwidth : natural range 20 to 40 := 24;
g_pwidth : natural range 2 to 40 := 24; --DB was 20 to 40
-- Duty cycle divider: D = 1/g_duty_cycle_div
g_duty_cycle_div : natural := 5
......@@ -269,7 +280,48 @@ package conv_common_gw_pkg is
pulse_o : out std_logic
);
end component conv_pulse_gen;
------------------------------------------------------------------------------
-- Controller for burst mode operation with configurable maximum pulse burst length and timeout
------------------------------------------------------------------------------
component conv_burst_ctrl is
generic
(
-- Short pulse width, in number of clk_i cycles
-- Default short pulse width (20 MHz clock): 250 ns = 5 clk cycles
g_pwidth : natural range 2 to 40 := 5;
-- Duty cycle divider: D = 1/g_duty_cycle_div
g_duty_cycle_div : natural := 200;
-- Number of pulses allowed before decision is made on whether to continue burst
-- Maximum number of pulses that can be received at the worst case 2MHz scenario
g_max_burst_len : natural := 1000; -- Check every "g_eval_burst_len" pulses
-- Burst is evaluated after g_max_burst_len or after a timeout g_burst_timeout set to 1 s.
g_burst_timeout : natural := 200000 -- 20000000 corresponds to 1 second timeout
-- 60000 corresponds to 3ms timeout
);
port
(
-- Clock and active-low reset inputs
clk_i : in std_logic;
rst_n_i : in std_logic;
-- Enable input, pulse generation is enabled when '1'
en_i : in std_logic;
pulse_burst_i : in std_logic;
pulse_burst_o : out std_logic;
-- Burst error output, pulses high for one clock cycle when a pulse arrives
-- within a burst rejection phase
burst_err_p_o : out std_logic
);
end component conv_burst_ctrl;
------------------------------------------------------------------------------
-- Converter board control registers
------------------------------------------------------------------------------
......@@ -461,7 +513,15 @@ package conv_common_gw_pkg is
-- Port for std_logic_vector field: 'Input failsafe state' in reg: 'LSR'
reg_lsr_rearfs_i : in std_logic_vector(5 downto 0);
-- Port for std_logic_vector field: 'Multicast address (from switch)' in reg: 'MSWR'
reg_oswr_switches_i : in std_logic_vector(31 downto 0)
reg_mswr_switches_i : in std_logic_vector(31 downto 0);
reg_oswr_switches_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'LS bits of 1-wire DS18B20U thermometer ID' in reg: '32 least significant bits of DS18B20U'
reg_ds18b20u_id_lsb_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'MS bits of 1-wire DS18B20U thermometer ID' in reg: '32 most significant bits of DS18B20U'
reg_ds18b20u_id_msb_i : in std_logic_vector(31 downto 0);
-- Port for std_logic_vector field: 'Temperature from DS18B20 thermometer' in reg: 'Board temperature'
reg_ds18b20u_temp_i : in std_logic_vector(15 downto 0)
);
end component conv_regs;
......@@ -583,5 +643,34 @@ package conv_common_gw_pkg is
);
end component conv_man_trig;
------------------------------------------------------------------------------
-- PPS trigger for one-wire master
------------------------------------------------------------------------------
component wf_decr_counter is
generic(g_counter_lgth : natural := 4); -- default length
port(
-- INPUTS
-- nanoFIP User Interface general signal
uclk_i : in std_logic; -- 40 MHz clock
-- Signal from the wf_reset_unit
counter_rst_i : in std_logic; -- resets counter to all '1'
-- Signals from any unit
counter_decr_i : in std_logic; -- decrement enable
counter_load_i : in std_logic; -- load enable; loads counter to counter_top_i
counter_top_i : in unsigned (g_counter_lgth-1 downto 0); -- load value
-- OUTPUTS
-- Signal to any unit
counter_o : out unsigned (g_counter_lgth-1 downto 0); -- counter
counter_is_zero_o : out std_logic); -- empty counter indication
end component wf_decr_counter;
end package conv_common_gw_pkg;
-----------------------------------------------------------------------------------
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