Commit 8cb00631 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

Merge branch 'tom-sep16' into tom-tmp-sep17

parents f1aadd5f 264a6373
......@@ -10,6 +10,6 @@
[submodule "hdl/ip_cores/gn4124-core"]
path = hdl/ip_cores/gn4124-core
url = git://ohwr.org/hdl-core-lib/gn4124-core.git
[submodule "hdl/ip_cores/etherbone-core"]
path = hdl/ip_cores/etherbone-core
url = git://ohwr.org/hdl-core-lib/etherbone-core.git
[submodule "hdl/ip_cores/ddr3-sp6-core"]
path = hdl/ip_cores/ddr3-sp6-core
url = git://ohwr.org/hdl-core-lib/ddr3-sp6-core.git
ddr3-sp6-core @ 8618c1e1
Subproject commit 8618c1e154c322be34cb069b62d8293527744dda
general-cores @ 4d36bf85
Subproject commit 0545c25b9b89db17db6f6a2c59752418056715bc
Subproject commit 4d36bf859fa6071acf11d86e1d57ab3a65a5f776
gn4124-core @ 017ef8c1
Subproject commit 5ffe9f5344e22262d1badeef21b8426d20948368
Subproject commit 017ef8c1453664414e871a7992496e15951f32fe
wr-cores @ 5bb966b6
Subproject commit c466a66b4d17173d3ee5e18af26a2d263a760aa0
Subproject commit 5bb966b6868537eb1bf1acf3dd04df95985966bb
files = [
"tdc_core_pkg.vhd",
"acam_databus_interface.vhd",
"acam_timecontrol_interface.vhd",
"carrier_info.vhd",
"clks_rsts_manager.vhd",
"data_engine.vhd",
"data_formatting.vhd",
"decr_counter.vhd",
"fmc_tdc_core.vhd",
"fmc_tdc_mezzanine.vhd",
"free_counter.vhd",
"incr_counter.vhd",
"leds_manager.vhd",
"local_pps_gen.vhd",
"reg_ctrl.vhd",
"start_retrig_ctrl.vhd",
"tdc_eic.vhd",
"wrabbit_sync.vhd",
"fmc_tdc_direct_readout.vhd",
"fmc_tdc_direct_readout_slave.vhd",
"fmc_tdc_direct_readout_slave_pkg.vhd",
"fmc_tdc_wrapper.vhd",
"timestamp_fifo.vhd",
"timestamp_fifo_wb.vhd",
"timestamp_fifo_wbgen2_pkg.vhd"
"tdc_core_pkg.vhd",
"acam_databus_interface.vhd",
"acam_timecontrol_interface.vhd",
"carrier_info.vhd",
"clks_rsts_manager.vhd",
"data_engine.vhd",
"data_formatting.vhd",
"decr_counter.vhd",
"fmc_tdc_core.vhd",
"fmc_tdc_mezzanine.vhd",
"free_counter.vhd",
"incr_counter.vhd",
"leds_manager.vhd",
"local_pps_gen.vhd",
"reg_ctrl.vhd",
"start_retrig_ctrl.vhd",
"tdc_eic.vhd",
"wrabbit_sync.vhd",
"fmc_tdc_direct_readout.vhd",
"fmc_tdc_direct_readout_slave.vhd",
"fmc_tdc_direct_readout_slave_pkg.vhd",
"fmc_tdc_wrapper.vhd",
"timestamp_fifo.vhd",
"timestamp_fifo_wb.vhd",
"timestamp_fifo_wbgen2_pkg.vhd",
"timestamp_convert_filter.vhd",
"tdc_dma_channel.vhd",
"tdc_dma_engine.vhd",
"tdc_buffer_control_regs.vhd",
"tdc_buffer_control_regs_wbgen2_pkg.vhd",
"tdc_ts_addsub.vhd",
"tdc_ts_sub.vhd",
"wbgen2_eic_nomask.vhd",
"dma_eic.vhd",
"tdc_onewire_wb.vhd",
"tdc_onewire_wbgen2_pkg.vhd"
];
......@@ -70,7 +70,6 @@ entity acam_timecontrol_interface is
-- Signals from the clk_rst_manager unit
(clk_i : in std_logic; -- 125 MHz clock
rst_i : in std_logic; -- reset
acam_refclk_r_edge_p_i : in std_logic; -- pulse upon ACAM RefClk rising edge
-- upc_p from the WRabbit or the local generator
utc_p_i : in std_logic;
......@@ -83,57 +82,31 @@ entity acam_timecontrol_interface is
-- for tstamps aquisition
deactivate_acq_p_i : in std_logic; -- acquisition deactivated
-- Signals from the ACAM chip
err_flag_i : in std_logic; -- ACAM error flag, active HIGH; through ACAM config
-- reg 11 is set to report for any HitFIFOs full flags
int_flag_i : in std_logic; -- ACAM interrupt flag, active HIGH; through ACAM config
-- reg 12 it is set to the MSB of Start#
-- OUTPUTS
-- Signals to the ACAM chip
start_from_fpga_o : out std_logic;
stop_dis_o : out std_logic;
-- Signals to the
acam_errflag_r_edge_p_o : out std_logic; -- ACAM ErrFlag rising edge
acam_errflag_f_edge_p_o : out std_logic; -- ACAM ErrFlag falling edge
acam_intflag_f_edge_p_o : out std_logic);-- ACAM IntFlag falling edge
stop_dis_o : out std_logic);
end acam_timecontrol_interface;
end entity;
--=================================================================================================
-- architecture declaration
--=================================================================================================
architecture rtl of acam_timecontrol_interface is
signal acam_intflag_f_edge_p : std_logic;
signal start_pulse, wait_for_utc, rst_n, wait_for_state_active : std_logic;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
rst_n <= not(rst_i);
---------------------------------------------------------------------------------------------------
-- IntFlag and ERRflag Input Synchronizers --
---------------------------------------------------------------------------------------------------
sync_err_flag : gc_sync_ffs
port map (
clk_i => clk_i,
rst_n_i => '1',
data_i => err_flag_i,
ppulse_o => acam_errflag_r_edge_p_o,
npulse_o => acam_errflag_f_edge_p_o);
sync_int_flag : gc_sync_ffs
port map (
clk_i => clk_i,
rst_n_i => '1',
data_i => int_flag_i,
npulse_o => acam_intflag_f_edge_p_o);
rst_n <= not(rst_i);
---------------------------------------------------------------------------------------------------
-- start_from_fpga_o generation --
......@@ -142,10 +115,10 @@ begin
-- after the state_active_p_i (coming from the data_engine unit).
-- The pulse is synchronous to the utc_p_i
start_pulse_from_fpga: process (clk_i)
start_pulse_from_fpga : process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' or deactivate_acq_p_i = '1' then
if rst_i = '1' or deactivate_acq_p_i = '1' then
wait_for_utc <= '0';
start_pulse <= '0';
wait_for_state_active <= '0';
......
#!/bin/bash
wbgen2 -V timestamp_fifo_wb.vhd -H record_full -p timestamp_fifo_wbgen2_pkg.vhd -K timestamp_fifo_regs.vh -s defines -C timestamp_fifo_regs.h -D wbgen/timestamp_fifo_wb.html wbgen/timestamp_fifo_wb.wb
wbgen2 -V tdc_onewire_wb.vhd -H record_full -p tdc_onewire_wbgen2_pkg.vhd -K timestamp_onewire_regs.vh -s defines -C tdc_onewire_regs.h wbgen/tdc_onewire_wb.wb
#wbgen2 -V tdc_buffer_control_regs.vhd -H record_full -p tdc_buffer_control_regs_wbgen2_pkg.vhd -K tdc_buffer_control_regs.vh -s defines -C tdc_buffer_control_regs.h wbgen/tdc_buffer_control_regs.wb
#don't do this, latest wbgen is buggy
#wbgen2 -V tdc_eic.vhd -s defines -C tdc_eic.h -D wbgen/tdc_eic.html wbgen/tdc_eic.wb
......@@ -77,8 +77,6 @@ use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific libraries
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
use work.gencores_pkg.all;
library UNISIM;
use UNISIM.vcomponents.all;
......@@ -89,7 +87,8 @@ use UNISIM.vcomponents.all;
entity clks_rsts_manager is
generic
(nb_of_reg : integer := 68);
(nb_of_reg : integer := 68;
g_simulation : boolean := false);
port
-- INPUTS
-- Clock signal from carrier board
......@@ -163,8 +162,9 @@ architecture rtl of clks_rsts_manager is
signal send_dac_word_r_edge_p, dac_only : std_logic;
signal pll_cs_n, dac_cs_n : std_logic;
-- Synchronizers
signal pll_status_synch, internal_rst_synch : std_logic;
signal rst_in_synch : std_logic := '0';
signal pll_status_synch, internal_rst_synch : std_logic_vector (1 downto 0);
signal rst_in_synch : std_logic_vector (1 downto 0) := "11";
signal acam_refclk_synch, send_dac_word_p_synch : std_logic_vector (2 downto 0);
-- Clock buffers
signal tdc_clk_buf : std_logic;
signal tdc_clk, acam_refclk : std_logic;
......@@ -173,9 +173,9 @@ architecture rtl of clks_rsts_manager is
signal rst_cnt : unsigned(7 downto 0) := "00000000";
-- SCLK generation
signal sclk : std_logic;
signal sclk_r_edge, sclk_f_edge, sclk_d1, sclk_d2: std_logic;
signal divider : unsigned(7 downto 0) := "00000000";
signal sclk_r_edge, sclk_f_edge, sclk_d1, sclk_d2 : std_logic;
signal divider : unsigned(4 downto 0) := "00000";
signal sclk_en : std_logic;
-- The PLL circuit AD9516-4 needs to be configured through 68 registers.
-- The values and addresses are obtained through the dedicated Analog Devices software & the datasheet.
constant REG_000 : t_byte := x"18";
......@@ -256,8 +256,8 @@ architecture rtl of clks_rsts_manager is
constant REG_231 : t_byte := x"00";
constant REG_232 : t_byte := x"01";
constant SIM_RST : std_logic_vector(31 downto 0):= x"00000400";
constant SYN_RST : std_logic_vector(31 downto 0):= x"00004E20";
constant SIM_RST : std_logic_vector(31 downto 0) := x"00000400";
constant SYN_RST : std_logic_vector(31 downto 0) := x"00004E20";
-- this value may still need adjustment according to the dispersion
-- in the performance of the PLL observed during the production tests
......@@ -281,7 +281,7 @@ begin
port map
(O => tdc_clk_buf, -- Buffer output
I => tdc_125m_clk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => tdc_125m_clk_n_i);-- Diff_n buffer input (connect directly to top-level port)
IB => tdc_125m_clk_n_i); -- Diff_n buffer input (connect directly to top-level port)
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
tdc_clk125_gbuf : BUFG
......@@ -331,7 +331,7 @@ begin
-- is released. Note that the level of the pll_status signal rather than its rising edge is used,
-- as in the case of a GN4124/VME reset during operation the PLL will remain locked, therefore no
-- rising edge would be detected.
rst_generation: process (clk_sys_i)
rst_generation : process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch = '0' then
......@@ -378,7 +378,7 @@ begin
port map
(O => acam_refclk,
I => acam_refclk_p_i, -- Diff_p buffer input (connect directly to top-level port)
IB => acam_refclk_n_i);-- Diff_n buffer input (connect directly to top-level port)
IB => acam_refclk_n_i); -- Diff_n buffer input (connect directly to top-level port)
---------------------------------------------------------------------------------------------------
acam_refclk_synchronizer : gc_sync_ffs
......@@ -406,7 +406,7 @@ begin
-- Synchronous process dac_word_reg: selection of the word to be sent to the DAC.
-- Upon initialization the default word is being sent; otherwise the word received through the VME
-- interface on the DAC_WORD register.
dac_word_reg: process (clk_sys_i)
dac_word_reg : process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch = '0' then
......@@ -431,11 +431,15 @@ begin
-- after a GN4124/VME command for the reconfiguration of the DAC (send_dac_word_p_i) or
-- after a White Rabbit command for the reconfiguration of the DAC(wrabbit_dac_wr_p_i)
---------------------------------------------------------------------------------------------------
pll_dac_initialization_seq: process (clk_sys_i)
pll_dac_initialization_seq : process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then
if rst_in_synch = '0' or send_dac_word_r_edge_p = '1' then
if rst_in_synch = '0' then
if g_simulation then
config_st <= done;
else
config_st <= config_start;
end if;
dac_only <= '0';
elsif wrabbit_dac_wr_p_i = '1' then
config_st <= config_start;
......@@ -447,7 +451,7 @@ begin
end process;
---------------------------------------------------------------------------------------------------
pll_dac_initialization_comb: process (config_st, dac_bit_index, pll_byte_index, pll_bit_index, sclk,
pll_dac_initialization_comb : process (config_st, dac_bit_index, pll_byte_index, pll_bit_index, sclk,
sclk_r_edge, sclk_f_edge, dac_only)
begin
case config_st is
......@@ -538,7 +542,7 @@ begin
end process;
---------------------------------------------------------------------------------------------------
pll_sclk_generator: process (clk_sys_i) -- transitions take place on the falling edge of sclk
pll_sclk_generator : process (clk_sys_i) -- transitions take place on the falling edge of sclk
begin
if rising_edge (clk_sys_i) then
if rst_in_synch = '0' then
......@@ -548,9 +552,9 @@ begin
else
sclk_d1 <= sclk;
sclk_d2 <= sclk_d1;
if divider(2) = '1' then
if divider = 0 then
sclk <= '0';
else
elsif divider = 15 then
sclk <= '1';
end if;
end if;
......@@ -574,7 +578,7 @@ begin
end process;
---------------------------------------------------------------------------------------------------
pll_index_control: process (clk_sys_i) -- counting of bits that are sent on the rising edges
pll_index_control : process (clk_sys_i) -- counting of bits that are sent on the rising edges
begin
if rising_edge (clk_sys_i) then
......@@ -610,7 +614,7 @@ begin
else x"00" & config_reg(pll_byte_index);
---------------------------------------------------------------------------------------------------
dac_index_control: process (clk_sys_i)
dac_index_control : process (clk_sys_i)
begin
if rising_edge (clk_sys_i) then -- counting of bits that are sent on the falling edges
......
......@@ -96,13 +96,16 @@ entity data_formatting is
retrig_nb_offset_i : in std_logic_vector(31 downto 0);
current_retrig_nb_i : in std_logic_vector(31 downto 0);
gen_fake_ts_enable_i : in std_logic;
gen_fake_ts_period_i : in std_logic_vector(27 downto 0);
gen_fake_ts_channel_i : in std_logic_vector(2 downto 0);
-- Signal from the WRabbit core or the one_hz_generator unit
utc_p_i : in std_logic;
-- OUTPUTS
timestamp_o : out std_logic_vector(127 downto 0);
timestamp_o : out t_acam_timestamp;
timestamp_valid_o : out std_logic
);
......@@ -140,12 +143,20 @@ architecture rtl of data_formatting is
signal previous_utc : std_logic_vector(31 downto 0);
signal timestamp_valid_int : std_logic;
signal fake_cnt_coarse : unsigned(27 downto 0);
signal fake_cnt_period : unsigned(27 downto 0);
signal fake_cnt_tai : unsigned(31 downto 0);
signal fake_ts_valid : std_logic;
signal timestamp_valid_int_d : std_logic;
signal raw_ts, raw_ts_d : t_raw_acam_timestamp;
--=================================================================================================
-- architecture begin
--=================================================================================================
begin
p_gen_timestamp_valid : process (clk_i)
begin
if rising_edge (clk_i) then
......@@ -153,6 +164,7 @@ begin
timestamp_valid_int <= '0';
else
timestamp_valid_int <= acam_tstamp1_ok_p_i or acam_tstamp2_ok_p_i;
timestamp_valid_int_d <= timestamp_valid_int;
end if;
end if;
end process;
......@@ -212,6 +224,26 @@ begin
end if;
end process;
p_tstamp_raw_latch : process(clk_i)
begin
if rising_edge(clk_i) then
if timestamp_valid_int = '1' then
raw_ts.seconds <= utc_i;
raw_ts.acam_bins <= acam_fine_timestamp;
raw_ts.acam_start_nb <= std_logic_vector(acam_start_nb);
raw_ts.slope <= acam_slope;
raw_ts.channel <= acam_channel;
raw_ts.roll_over_incr_recent <= roll_over_incr_recent_i;
raw_ts.clk_i_cycles_offset <= clk_i_cycles_offset_i(7 downto 0);
raw_ts.roll_over_nb <= roll_over_nb_i(15 downto 0);
raw_ts.retrig_nb_offset <= retrig_nb_offset_i(8 downto 0);
raw_ts.current_retrig_nb <= current_retrig_nb_i(8 downto 0);
end if;
raw_ts_d <= raw_ts;
end if;
end process;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
reg_info_of_previous_sec : process (clk_i)
begin
......@@ -238,6 +270,7 @@ begin
un_acam_start_nb <= unsigned(acam_start_nb_32);
un_current_retrig_nb_offset <= unsigned(retrig_nb_offset_i);
un_current_roll_over_nb <= unsigned(roll_over_nb_i);
un_current_retrig_from_roll_over <= shift_left(un_current_roll_over_nb-1, 8) when roll_over_incr_recent_i = '1' and un_acam_start_nb > 192 and un_current_roll_over_nb > 0
else shift_left(un_current_roll_over_nb, 8);
......@@ -335,17 +368,60 @@ begin
metadata(2 downto 0) <= acam_channel;
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
full_timestamp(31 downto 0) <= fine_time;
full_timestamp(63 downto 32) <= coarse_time;
full_timestamp(95 downto 64) <= utc;
full_timestamp(127 downto 96) <= metadata;
process(clk_i)
begin
if rising_edge(clk_i) then
if gen_fake_ts_enable_i = '0' then
fake_cnt_coarse <= (others => '0');
fake_cnt_tai <= (others => '0');
fake_cnt_period <= (others => '0');
else
if unsigned(gen_fake_ts_period_i) = fake_cnt_period then
fake_cnt_period <= (others => '0');
fake_ts_valid <= '1';
else
fake_cnt_period <= fake_cnt_period + 1;
fake_ts_valid <= '0';
end if;
if fake_cnt_coarse = 124999999 then
fake_cnt_coarse <= (others => '0');
fake_cnt_tai <= fake_cnt_tai + 1;
else
fake_cnt_coarse <= fake_cnt_coarse + 1;
end if;
end if;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
timestamp_o <= full_timestamp;
timestamp_valid_o <= timestamp_valid_int;
if rst_i = '1' then
else
if(gen_fake_ts_enable_i = '1' and fake_ts_valid = '1')then
timestamp_o.slope <= '1';
timestamp_o.channel <= gen_fake_ts_channel_i;
timestamp_o.n_bins <= (others => '0');
timestamp_o.coarse <= std_logic_vector(resize(fake_cnt_coarse, 32));
timestamp_o.tai <= std_logic_vector(fake_cnt_tai);
timestamp_valid_o <= '1';
elsif(timestamp_valid_int_d = '1') then
timestamp_o.raw <= raw_ts_d;
timestamp_o.slope <= acam_slope;
timestamp_o.channel <= acam_channel;
timestamp_o.n_bins <= fine_time(16 downto 0);
timestamp_o.coarse <= coarse_time;
timestamp_o.tai <= utc(31 downto 0);
timestamp_o.meta <= x"000" & std_logic_vector(acam_start_nb(6 downto 0)) & fine_time(12 downto 0);
timestamp_valid_o <= '1';
else
timestamp_valid_o <= '0';
end if;
end if;
end if;
end process;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -131,7 +131,10 @@ entity fmc_tdc_wrapper is
-- reduces some timeouts to speed up simulation
g_simulation : boolean := false;
-- implement direct TDC timestamp readout FIFO, used in the WR Node projects
g_with_direct_readout : boolean := false
g_with_direct_readout : boolean := false;
g_use_dma_readout : boolean := false;
g_use_fake_timestamps_for_sim : boolean := false
);
port
......@@ -184,12 +187,6 @@ entity fmc_tdc_wrapper is
tdc_led_trig4_o : out std_logic; -- amber led on front pannel, Ch.4 enable
tdc_led_trig5_o : out std_logic; -- amber led on front pannel, Ch.5 enable
-- Input Logic on TDC mezzanine (not used currently)
tdc_in_fpga_1_i : in std_logic; -- Ch.1 for ACAM, also received by FPGA
tdc_in_fpga_2_i : in std_logic; -- Ch.2 for ACAM, also received by FPGA
tdc_in_fpga_3_i : in std_logic; -- Ch.3 for ACAM, also received by FPGA
tdc_in_fpga_4_i : in std_logic; -- Ch.4 for ACAM, also received by FPGA
tdc_in_fpga_5_i : in std_logic; -- Ch.5 for ACAM, also received by FPGA
-- I2C EEPROM interface on TDC mezzanine
mezz_scl_o : out std_logic;
......@@ -220,13 +217,21 @@ entity fmc_tdc_wrapper is
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
direct_slave_i : in t_wishbone_slave_in;
direct_slave_i : in t_wishbone_slave_in := cc_dummy_slave_in;
direct_slave_o : out t_wishbone_slave_out;
dma_wb_o : out t_wishbone_master_out;
dma_wb_i : in t_wishbone_master_in := cc_dummy_master_in;
irq_o : out std_logic;
-- local PLL clock output (for WR PTP Core clock disciplining)
clk_125m_tdc_o : out std_logic
clk_125m_tdc_o : out std_logic;
sim_timestamp_i : in t_tdc_timestamp := c_dummy_timestamp;
sim_timestamp_valid_i : in std_logic := '0';
sim_timestamp_ready_o : out std_logic
);
end fmc_tdc_wrapper;
......@@ -287,6 +292,10 @@ architecture rtl of fmc_tdc_wrapper is
(c_slave_direct => x"00008000",
c_slave_regs => x"00008000");
signal wr_dac_din, wr_dac_sclk, wr_dac_sync_n : std_logic;
signal pll_cs : std_logic;
begin
......@@ -326,15 +335,16 @@ begin
end generate gen_with_direct_readout;
gen_without_direct_readout: if not g_with_direct_readout generate
gen_without_direct_readout : if not g_with_direct_readout generate
cnx_master_out(c_slave_regs) <= slave_i;
slave_o <= cnx_master_in(c_slave_regs);
end generate gen_without_direct_readout;
cmp_tdc_clks_rsts_mgment : clks_rsts_manager
cmp_tdc_clks_rsts_mgment : entity work.clks_rsts_manager
generic map
(nb_of_reg => 68)
(nb_of_reg => 68,
g_simulation => g_simulation)
port map
(clk_sys_i => clk_sys_i,
acam_refclk_p_i => acam_refclk_p_i,
......@@ -344,45 +354,74 @@ begin
rst_n_i => rst_n_a_i,
pll_sdo_i => pll_sdo_i,
pll_status_i => pll_status_i,
send_dac_word_p_i => send_dac_word_p,
dac_word_i => dac_word,
send_dac_word_p_i => '0',
dac_word_i => x"000000",
acam_refclk_r_edge_p_o => acam_refclk_r_edge_p,
wrabbit_dac_value_i => tm_dac_value_i,
wrabbit_dac_wr_p_i => tm_dac_wr_i,
wrabbit_dac_value_i => x"000000",
wrabbit_dac_wr_p_i => '0',
internal_rst_o => rst_125m_mezz,
pll_cs_n_o => pll_cs_o,
pll_cs_n_o => pll_cs,
pll_dac_sync_n_o => pll_dac_sync,
pll_sdi_o => pll_sdi,
pll_sclk_o => pll_sclk,
tdc_125m_clk_o => clk_125m_mezz,
pll_status_o => open);
U_WR_DAC : gc_serial_dac
generic map (
g_num_data_bits => 16,
g_num_extra_bits => 8,
g_num_cs_select => 1,
g_sclk_polarity => 0)
port map (
clk_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
value_i => tm_dac_value_i(15 downto 0),
cs_sel_i => "1",
load_i => tm_dac_wr_i,
sclk_divsel_i => "010",
dac_cs_n_o(0) => wr_dac_sync_n,
dac_sclk_o => wr_dac_sclk,
dac_sdata_o => wr_dac_din);
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
rst_125m_mezz_n <= not rst_125m_mezz;
pll_dac_sync_o <= pll_dac_sync;
pll_sdi_o <= pll_sdi;
pll_sclk_o <= pll_sclk;
pll_dac_sync_o <= wr_dac_sync_n;
pll_sdi_o <= pll_sdi when pll_cs = '0' else wr_dac_din;
pll_sclk_o <= pll_sclk when pll_cs = '0' else wr_dac_sclk;
pll_cs_o <= pll_cs;
clk_125m_tdc_o <= clk_125m_mezz;
---------------------------------------------------------------------------------------------------
-- TDC BOARD --
---------------------------------------------------------------------------------------------------
cmp_tdc_mezz : fmc_tdc_mezzanine
cmp_tdc_mezz : entity work.fmc_tdc_mezzanine
generic map
(g_span => 32,
g_width => 32,
g_simulation => g_simulation)
g_simulation => g_simulation,
g_use_dma_readout => g_use_dma_readout,
g_use_fake_timestamps_for_sim => g_use_fake_timestamps_for_sim)
port map
-- 62M5 clk and reset
(clk_sys_i => clk_sys_i,
rst_sys_n_i => rst_sys_n_i,
-- 125M clk and reset
clk_tdc_i => clk_125m_mezz,
rst_tdc_i => rst_125m_mezz,
rst_tdc_n_i => rst_125m_mezz_n,
-- Wishbone
slave_i => cnx_master_out(c_slave_regs),
slave_o => cnx_master_in(c_slave_regs),
dma_wb_i => dma_wb_i,
dma_wb_o => dma_wb_o,
-- Interrupt line from EIC
wb_irq_o => irq_o,
......@@ -418,12 +457,6 @@ begin
tdc_led_trig3_o => tdc_led_trig3_o,
tdc_led_trig4_o => tdc_led_trig4_o,
tdc_led_trig5_o => tdc_led_trig5_o,
-- Input channels to FPGA (not used)
tdc_in_fpga_1_i => tdc_in_fpga_1_i,
tdc_in_fpga_2_i => tdc_in_fpga_2_i,
tdc_in_fpga_3_i => tdc_in_fpga_3_i,
tdc_in_fpga_4_i => tdc_in_fpga_4_i,
tdc_in_fpga_5_i => tdc_in_fpga_5_i,
-- WISHBONE interface with the GN4124 core
-- White Rabbit
......@@ -447,15 +480,19 @@ begin
-- 1-Wire on TDC mezzanine
onewire_b => mezz_one_wire_b,
direct_timestamp_o => direct_timestamp,
direct_timestamp_stb_o => direct_timestamp_wr);
direct_timestamp_stb_o => direct_timestamp_wr,
sim_timestamp_ready_o => sim_timestamp_ready_o,
sim_timestamp_valid_i => sim_timestamp_valid_i,
sim_timestamp_i => sim_timestamp_i);
mezz_scl_o <= '0' when tdc_scl_out ='0' and tdc_scl_oen = '0' else '1';
mezz_sda_o <= '0' when tdc_sda_out ='0' and tdc_sda_oen = '0' else '1';
mezz_scl_o <= '0' when tdc_scl_out = '0' and tdc_scl_oen = '0' else '1';
mezz_sda_o <= '0' when tdc_sda_out = '0' and tdc_sda_oen = '0' else '1';
end rtl;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
----------------------------------------------------------------------------------------------------
This diff is collapsed.
......@@ -81,18 +81,20 @@ use work.wishbone_pkg.all;
entity reg_ctrl is
generic
(g_span : integer := 32;
g_width : integer := 32);
(
g_span : integer := 32;
g_width : integer := 32
);
port
(
clk_sys_i : in std_logic;
rst_n_sys_i : in std_logic; -- global reset, synched to clk_sys
rst_sys_n_i : in std_logic; -- global reset, synched to clk_sys
clk_tdc_i : in std_logic;
rst_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
slave_i: in t_wishbone_slave_in; -- WB interface (clk_sys domain)
slave_o: out t_wishbone_slave_out;
slave_i : in t_wishbone_slave_in; -- WB interface (clk_sys domain)
slave_o : out t_wishbone_slave_out;
-- Signals from the data_engine unit: configuration regs read back from the ACAM
acam_config_rdbk_i : in config_vector; -- array keeping values read back from ACAM regs 0-7, 11, 12, 14
......@@ -126,6 +128,11 @@ entity reg_ctrl is
acam_rdbk_ififo2_p_o : out std_logic; -- enables reading of ACAM reg 9
acam_rdbk_start01_p_o : out std_logic; -- enables reading of ACAM reg 10
gen_fake_ts_enable_o : out std_logic;
gen_fake_ts_period_o : out std_logic_vector(27 downto 0);
gen_fake_ts_channel_o : out std_logic_vector(2 downto 0);
-- Signals to the clks_resets_manager unit
send_dac_word_p_o : out std_logic; -- initiates the reconfiguration of the DAC
dac_word_o : out std_logic_vector(23 downto 0);
......@@ -133,7 +140,7 @@ entity reg_ctrl is
-- Signal to the one_hz_gen unit
load_utc_p_o : out std_logic;
starting_utc_o : out std_logic_vector(g_width-1 downto 0);
irq_tstamp_threshold_o: out std_logic_vector(g_width-1 downto 0); -- threshold in number of timestamps
irq_tstamp_threshold_o : out std_logic_vector(g_width-1 downto 0); -- threshold in number of timestamps
irq_time_threshold_o : out std_logic_vector(g_width-1 downto 0); -- threshold in number of ms
one_hz_phase_o : out std_logic_vector(g_width-1 downto 0); -- for debug only
......@@ -144,7 +151,12 @@ entity reg_ctrl is
wrabbit_ctrl_reg_o : out std_logic_vector(g_width-1 downto 0); --
-- Signal to the acam_timecontrol_interface unit -- eva: i think it s not needed
start_phase_o : out std_logic_vector(g_width-1 downto 0));
start_phase_o : out std_logic_vector(g_width-1 downto 0);
int_flag_dly_ce_o : out std_logic;
int_flag_dly_inc_o : out std_logic;
int_flag_dly_rst_o : out std_logic
);
end reg_ctrl;
......@@ -155,7 +167,7 @@ end reg_ctrl;
architecture rtl of reg_ctrl is
signal acam_config : config_vector;
signal reg_adr,reg_adr_pipe0 : std_logic_vector(7 downto 0);
signal reg_adr, reg_adr_pipe0 : std_logic_vector(7 downto 0);
signal starting_utc, acam_inputs_en, start_phase : std_logic_vector(g_width-1 downto 0);
signal ctrl_reg, one_hz_phase, irq_tstamp_threshold : std_logic_vector(g_width-1 downto 0);
signal irq_time_threshold : std_logic_vector(g_width-1 downto 0);
......@@ -174,10 +186,10 @@ architecture rtl of reg_ctrl is
signal dat_out_pipe2, dat_out_pipe3 : std_logic_vector(g_span-1 downto 0);
signal cyc_in_progress : std_logic;
signal cyc2_in_progress : std_logic;
signal wb_in : t_wishbone_slave_in;
signal wb_out : t_wishbone_slave_out;
signal rst_n_tdc : std_logic;
......@@ -190,8 +202,6 @@ architecture rtl of reg_ctrl is
begin
rst_n_tdc <= not rst_tdc_i;
wb_out.stall <= '0';
wb_out.err <= '0';
wb_out.rty <= '0';
......@@ -199,11 +209,11 @@ begin
u_sync_tdc_reset : gc_sync_ffs
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_sys_i,
data_i => rst_n_tdc,
rst_n_i => rst_sys_n_i,
data_i => rst_tdc_n_i,
synced_o => cc_rst_n);
cc_rst_n_or_sys <= cc_rst_n and rst_n_sys_i;
cc_rst_n_or_sys <= cc_rst_n and rst_sys_n_i;
cmp_clks_crossing : xwb_clock_crossing
port map
......@@ -212,7 +222,7 @@ begin
slave_i => slave_i,
slave_o => slave_o,
master_clk_i => clk_tdc_i,
master_rst_n_i => rst_n_tdc,
master_rst_n_i => rst_tdc_n_i,
master_i => wb_out,
master_o => wb_in);
......@@ -228,12 +238,12 @@ begin
TDCconfig_ack_generator : process (clk_tdc_i)
begin
if rising_edge (clk_tdc_i) then
if rst_n_tdc = '0' then
if rst_tdc_n_i = '0' then
wb_out.ack <= '0';
ack_out_pipe1 <= '0';
ack_out_pipe0 <= '0';
cyc_in_progress <= '0';
elsif(wb_in.cyc = '0') then
elsif(wb_in.cyc /= '1') then
ack_out_pipe1 <= '0';
ack_out_pipe0 <= '0';
cyc_in_progress <= '0';
......@@ -259,18 +269,18 @@ begin
ACAM_config_reg_reception : process (clk_tdc_i)
begin
if rising_edge (clk_tdc_i) then
if rst_tdc_i = '1' then
acam_config(0) <= (others =>'0');
acam_config(1) <= (others =>'0');
acam_config(2) <= (others =>'0');
acam_config(3) <= (others =>'0');
acam_config(4) <= (others =>'0');
acam_config(5) <= (others =>'0');
acam_config(6) <= (others =>'0');
acam_config(7) <= (others =>'0');
acam_config(8) <= (others =>'0');
acam_config(9) <= (others =>'0');
acam_config(10) <= (others =>'0');
if rst_tdc_n_i = '0' then
acam_config(0) <= (others => '0');
acam_config(1) <= (others => '0');
acam_config(2) <= (others => '0');
acam_config(3) <= (others => '0');
acam_config(4) <= (others => '0');
acam_config(5) <= (others => '0');
acam_config(6) <= (others => '0');
acam_config(7) <= (others => '0');
acam_config(8) <= (others => '0');
acam_config(9) <= (others => '0');
acam_config(10) <= (others => '0');
elsif wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then -- WISHBONE writes
......@@ -339,20 +349,28 @@ begin
-- o one_hz_phase : eva: think it s not used
-- o start_phase : eva: think it s not used
TDCcore_config_reg_reception: process (clk_tdc_i)
TDCcore_config_reg_reception : process (clk_tdc_i)
begin
if rising_edge (clk_tdc_i) then
if rst_tdc_i ='1' then
acam_inputs_en <= (others =>'0');
starting_utc <= (others =>'0');
start_phase <= (others =>'0');
one_hz_phase <= (others =>'0');
wrabbit_ctrl_reg <= (others =>'0');
if rst_tdc_n_i = '0' then
acam_inputs_en <= (others => '0');
starting_utc <= (others => '0');
start_phase <= (others => '0');
one_hz_phase <= (others => '0');
wrabbit_ctrl_reg <= (others => '0');
irq_tstamp_threshold <= x"00000001"; -- default 256 timestamps: full memory
irq_time_threshold <= x"00000001"; -- default 200 ms
dac_word <= c_DEFAULT_DAC_WORD; -- default DAC Vout = 1.65
gen_fake_ts_enable_o <= '0';
int_flag_dly_rst_o <= '0';
int_flag_dly_ce_o <= '0';
int_flag_dly_inc_o <= '0';
cyc2_in_progress <= '0';
elsif wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then
cyc2_in_progress <= '1';
if reg_adr = c_STARTING_UTC_ADR then
starting_utc <= wb_in.dat;
......@@ -386,7 +404,23 @@ begin
wrabbit_ctrl_reg <= wb_in.dat;
end if;
if reg_adr = c_TEST0_ADR then
gen_fake_ts_enable_o <= wb_in.dat(31);
gen_fake_ts_channel_o <= wb_in.dat(30 downto 28);
gen_fake_ts_period_o <= wb_in.dat(27 downto 0);
end if;
int_flag_dly_ce_o <= '0';
if reg_adr = c_TEST1_ADR then
int_flag_dly_ce_o <= wb_in.dat(0) and not cyc2_in_progress;
int_flag_dly_inc_o <= wb_in.dat(1);
int_flag_dly_rst_o <= wb_in.dat(2);
end if;
else
int_flag_dly_ce_o <= '0';
cyc2_in_progress <= '0';
end if;
end if;
end process;
......@@ -412,12 +446,12 @@ begin
TDCcore_ctrl_reg_reception : process (clk_tdc_i)
begin
if rising_edge (clk_tdc_i) then
if rst_tdc_i = '1' then
ctrl_reg <= (others =>'0');
if rst_tdc_n_i = '0' then
ctrl_reg <= (others => '0');
clear_ctrl_reg <= '0';
elsif clear_ctrl_reg = '1' then
ctrl_reg <= (others =>'0');
ctrl_reg <= (others => '0');
clear_ctrl_reg <= '0';
elsif wb_in.cyc = '1' and wb_in.stb = '1' and wb_in.we = '1' then
......@@ -447,7 +481,7 @@ begin
-- Pulse_stretcher: Increases the width of the send_dac_word_p pulse so that it can be sampled
-- by the 20 MHz clock of the clks_rsts_manager that is communicating with the DAC.
Pulse_stretcher: incr_counter
Pulse_stretcher : incr_counter
generic map
(width => 3)
port map
......
......@@ -130,29 +130,33 @@ library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
library unisim;
use unisim.vcomponents.all;
--=================================================================================================
-- Entity declaration for start_retrig_ctrl
--=================================================================================================
entity start_retrig_ctrl is
generic
(g_width : integer := 32);
port
-- INPUTS
-- Signal from the clk_rst_manager
(clk_i : in std_logic;
rst_i : in std_logic;
-- Signal from the acam_timecontrol_interface
acam_intflag_f_edge_p_i : in std_logic;
int_flag_i : in std_logic;
r_int_flag_dly_rst_i : in std_logic;
r_int_flag_dly_inc_i : in std_logic;
r_int_flag_dly_ce_i : in std_logic;
-- Signal from the one_hz_generator unit
utc_p_i : in std_logic;
-- OUTPUTS
-- Signals to the data_formatting unit
current_retrig_nb_o : out std_logic_vector(g_width-1 downto 0);
current_retrig_nb_o : out std_logic_vector(31 downto 0);
roll_over_incr_recent_o : out std_logic;
clk_i_cycles_offset_o : out std_logic_vector(g_width-1 downto 0);
roll_over_nb_o : out std_logic_vector(g_width-1 downto 0);
retrig_nb_offset_o : out std_logic_vector(g_width-1 downto 0));
clk_i_cycles_offset_o : out std_logic_vector(31 downto 0);
roll_over_nb_o : out std_logic_vector(31 downto 0);
retrig_nb_offset_o : out std_logic_vector(31 downto 0));
end start_retrig_ctrl;
......@@ -163,13 +167,14 @@ end start_retrig_ctrl;
architecture rtl of start_retrig_ctrl is
signal clk_i_cycles_offset : std_logic_vector(g_width-1 downto 0);
signal current_cycles : std_logic_vector(g_width-1 downto 0);
signal current_retrig_nb : std_logic_vector(g_width-1 downto 0);
signal retrig_nb_offset : std_logic_vector(g_width-1 downto 0);
signal clk_i_cycles_offset : std_logic_vector(31 downto 0);
signal current_cycles : std_logic_vector(31 downto 0);
signal current_retrig_nb : std_logic_vector(31 downto 0);
signal retrig_nb_offset : std_logic_vector(31 downto 0);
signal retrig_p : std_logic;
signal roll_over_c : unsigned(g_width-1 downto 0);
signal roll_over_c : unsigned(31 downto 0);
signal int_flag_stb_p, int_flag_dly, int_flag, int_flag_d, int_flag_p : std_logic;
--=================================================================================================
-- architecture begin
......@@ -233,12 +238,60 @@ begin
-- These two counters keep a track of the current internal start retrigger
-- of the ACAM in parallel with the ACAM itself. Counting up to c_ACAM_RETRIG_PERIOD = 64
retrig_period_counter: free_counter -- retrigger periods
iodelay2_bus : IODELAY2
generic map (
DATA_RATE => "SDR",
IDELAY_VALUE => 0,
IDELAY_TYPE => "VARIABLE_FROM_ZERO",
COUNTER_WRAPAROUND => "STAY_AT_LIMIT",
DELAY_SRC => "IDATAIN",
SERDES_MODE => "NONE",
SIM_TAPDELAY_VALUE => 75)
port map (
-- required datapath
IDATAIN => int_flag_i,
DATAOUT => int_flag_dly,
T => '1',
-- inactive data connections
DATAOUT2 => open,
DOUT => open,
ODATAIN => '0',
TOUT => open,
-- connect up the clocks
IOCLK0 => clk_i, -- High speed clock for calibration for SDR/DDR
IOCLK1 => '0', -- High speed clock for calibration for DDR
CLK => clk_i,
CAL => '0',
INC => r_int_flag_dly_inc_i,
CE => r_int_flag_dly_ce_i,
BUSY => open,
RST => r_int_flag_dly_rst_i);
p_sample_int_flag : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_i = '1' then
int_flag_d <= '0';
int_flag <= '0';
else
int_flag <= int_flag_dly;
int_flag_d <= int_flag;
end if;
end if;
end process;
int_flag_p <= not int_flag and int_flag_d;
retrig_period_counter : free_counter -- retrigger periods
generic map
(width => g_width)
(width => 32)
port map
(clk_i => clk_i,
rst_i => acam_intflag_f_edge_p_i,
rst_i => int_flag_p,
counter_en_i => '1',
counter_top_i => c_ACAM_RETRIG_PERIOD,
-------------------------------------------
......@@ -246,12 +299,12 @@ begin
counter_o => current_cycles);
-------------------------------------------
retrig_nb_counter: incr_counter -- number of retriggers counting from 0 to 255 and restarting
retrig_nb_counter : incr_counter -- number of retriggers counting from 0 to 255 and restarting
generic map -- through the acam_intflag_f_edge_p_i
(width => g_width)
(width => 32)
port map
(clk_i => clk_i,
rst_i => acam_intflag_f_edge_p_i,
rst_i => int_flag_p,
counter_top_i => x"00000100",
counter_incr_en_i => retrig_p,
counter_is_full_o => open,
......@@ -261,18 +314,18 @@ begin
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- This counter keeps track of the number of overflows of the ACAM counter within one second
roll_over_counter: process (clk_i)
roll_over_counter : process (clk_i)
begin
if rising_edge (clk_i) then
if utc_p_i = '1' and acam_intflag_f_edge_p_i = '0' then
if utc_p_i = '1' and int_flag_p = '0' then
roll_over_c <= x"00000000";
-- the following case covers the rare possibility when utc_p_i and acam_intflag_f_edge_p_i
-- arrive on the exact same moment
elsif utc_p_i = '1' and acam_intflag_f_edge_p_i = '1' then
elsif utc_p_i = '1' and int_flag_p = '1' then
roll_over_c <= x"00000001";
elsif acam_intflag_f_edge_p_i = '1' then
elsif int_flag_p = '1' then
roll_over_c <= roll_over_c + "1";
end if;
end if;
......@@ -282,12 +335,12 @@ begin
-- When a new second starts, all values are captured and stored as offsets.
-- when a timestamp arrives, these offsets will be subtracted in order
-- to base the final timestamp with respect to the current second.
capture_offset: process (clk_i)
capture_offset : process (clk_i)
begin
if rising_edge (clk_i) then
if rst_i ='1' then
clk_i_cycles_offset <= (others=>'0');
retrig_nb_offset <= (others=>'0');
if rst_i = '1' then
clk_i_cycles_offset <= (others => '0');
retrig_nb_offset <= (others => '0');
elsif utc_p_i = '1' then
clk_i_cycles_offset <= current_cycles;
......
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC DMA Buffer Control Registers
---------------------------------------------------------------------------------------
-- File : tdc_buffer_control_regs.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_buffer_control_regs.wb
-- Created : Mon Aug 6 23:30:18 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_buffer_control_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.TDC_BUF_wbgen2_pkg.all;
entity tdc_buffer_control_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_TDC_BUF_in_registers;
regs_o : out t_TDC_BUF_out_registers
);
end tdc_buffer_control_wb;
architecture syn of tdc_buffer_control_wb is
signal tdc_buf_csr_enable_int : std_logic ;
signal tdc_buf_csr_irq_timeout_int : std_logic_vector(9 downto 0);
signal tdc_buf_csr_burst_size_int : std_logic_vector(9 downto 0);
signal tdc_buf_csr_switch_buffers_dly0 : std_logic ;
signal tdc_buf_csr_switch_buffers_int : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= slave_i.dat;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
tdc_buf_csr_enable_int <= '0';
tdc_buf_csr_irq_timeout_int <= "0000000000";
tdc_buf_csr_burst_size_int <= "0000000000";
tdc_buf_csr_switch_buffers_int <= '0';
regs_o.tdc_buf_csr_done_load_o <= '0';
regs_o.tdc_buf_csr_overflow_load_o <= '0';
regs_o.tdc_buf_cur_base_load_o <= '0';
regs_o.tdc_buf_cur_size_size_load_o <= '0';
regs_o.tdc_buf_cur_size_valid_load_o <= '0';
regs_o.tdc_buf_next_base_load_o <= '0';
regs_o.tdc_buf_next_size_size_load_o <= '0';
regs_o.tdc_buf_next_size_valid_load_o <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
tdc_buf_csr_switch_buffers_int <= '0';
regs_o.tdc_buf_csr_done_load_o <= '0';
regs_o.tdc_buf_csr_overflow_load_o <= '0';
regs_o.tdc_buf_cur_base_load_o <= '0';
regs_o.tdc_buf_cur_size_size_load_o <= '0';
regs_o.tdc_buf_cur_size_valid_load_o <= '0';
regs_o.tdc_buf_next_base_load_o <= '0';
regs_o.tdc_buf_next_size_size_load_o <= '0';
regs_o.tdc_buf_next_size_valid_load_o <= '0';
ack_in_progress <= '0';
else
regs_o.tdc_buf_csr_done_load_o <= '0';
regs_o.tdc_buf_csr_overflow_load_o <= '0';
regs_o.tdc_buf_cur_base_load_o <= '0';
regs_o.tdc_buf_cur_size_size_load_o <= '0';
regs_o.tdc_buf_cur_size_valid_load_o <= '0';
regs_o.tdc_buf_next_base_load_o <= '0';
regs_o.tdc_buf_next_size_size_load_o <= '0';
regs_o.tdc_buf_next_size_valid_load_o <= '0';
end if;
else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (slave_i.we = '1') then
tdc_buf_csr_enable_int <= wrdata_reg(0);
tdc_buf_csr_irq_timeout_int <= wrdata_reg(10 downto 1);
tdc_buf_csr_burst_size_int <= wrdata_reg(20 downto 11);
tdc_buf_csr_switch_buffers_int <= wrdata_reg(21);
regs_o.tdc_buf_csr_done_load_o <= '1';
regs_o.tdc_buf_csr_overflow_load_o <= '1';
end if;
rddata_reg(0) <= tdc_buf_csr_enable_int;
rddata_reg(10 downto 1) <= tdc_buf_csr_irq_timeout_int;
rddata_reg(20 downto 11) <= tdc_buf_csr_burst_size_int;
rddata_reg(21) <= '0';
rddata_reg(22) <= regs_i.tdc_buf_csr_done_i;
rddata_reg(23) <= regs_i.tdc_buf_csr_overflow_i;
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "001" =>
if (slave_i.we = '1') then
regs_o.tdc_buf_cur_base_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= regs_i.tdc_buf_cur_base_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.tdc_buf_cur_count_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "011" =>
if (slave_i.we = '1') then
regs_o.tdc_buf_cur_size_size_load_o <= '1';
regs_o.tdc_buf_cur_size_valid_load_o <= '1';
end if;
rddata_reg(29 downto 0) <= regs_i.tdc_buf_cur_size_size_i;
rddata_reg(30) <= regs_i.tdc_buf_cur_size_valid_i;
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (slave_i.we = '1') then
regs_o.tdc_buf_next_base_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= regs_i.tdc_buf_next_base_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "101" =>
if (slave_i.we = '1') then
regs_o.tdc_buf_next_size_size_load_o <= '1';
regs_o.tdc_buf_next_size_valid_load_o <= '1';
end if;
rddata_reg(29 downto 0) <= regs_i.tdc_buf_next_size_size_i;
rddata_reg(30) <= regs_i.tdc_buf_next_size_valid_i;
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
slave_o.dat <= rddata_reg;
-- Enable acquisition
regs_o.tdc_buf_csr_enable_o <= tdc_buf_csr_enable_int;
-- IRQ Timeout (ms)
regs_o.tdc_buf_csr_irq_timeout_o <= tdc_buf_csr_irq_timeout_int;
-- Burst size (timestamps)
regs_o.tdc_buf_csr_burst_size_o <= tdc_buf_csr_burst_size_int;
-- Switch buffers
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
tdc_buf_csr_switch_buffers_dly0 <= '0';
regs_o.tdc_buf_csr_switch_buffers_o <= '0';
elsif rising_edge(clk_sys_i) then
tdc_buf_csr_switch_buffers_dly0 <= tdc_buf_csr_switch_buffers_int;
regs_o.tdc_buf_csr_switch_buffers_o <= tdc_buf_csr_switch_buffers_int and (not tdc_buf_csr_switch_buffers_dly0);
end if;
end process;
-- Burst complete
regs_o.tdc_buf_csr_done_o <= wrdata_reg(22);
-- DMA overflow
regs_o.tdc_buf_csr_overflow_o <= wrdata_reg(23);
-- Base address
regs_o.tdc_buf_cur_base_o <= wrdata_reg(31 downto 0);
-- Number of data samples
-- Size
regs_o.tdc_buf_cur_size_size_o <= wrdata_reg(29 downto 0);
-- Valid flag
regs_o.tdc_buf_cur_size_valid_o <= wrdata_reg(30);
-- Base address
regs_o.tdc_buf_next_base_o <= wrdata_reg(31 downto 0);
-- Size (in transfers)
regs_o.tdc_buf_next_size_size_o <= wrdata_reg(29 downto 0);
-- Valid flag
regs_o.tdc_buf_next_size_valid_o <= wrdata_reg(30);
rwaddr_reg <= slave_i.adr(4 downto 2);
slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc);
slave_o.err <= '0';
slave_o.rty <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o.ack <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC DMA Buffer Control Registers
---------------------------------------------------------------------------------------
-- File : tdc_buffer_control_regs_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_buffer_control_regs.wb
-- Created : Mon Aug 6 23:30:18 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_buffer_control_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package TDC_BUF_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_TDC_BUF_in_registers is record
tdc_buf_csr_done_i : std_logic;
tdc_buf_csr_overflow_i : std_logic;
tdc_buf_cur_base_i : std_logic_vector(31 downto 0);
tdc_buf_cur_count_i : std_logic_vector(31 downto 0);
tdc_buf_cur_size_size_i : std_logic_vector(29 downto 0);
tdc_buf_cur_size_valid_i : std_logic;
tdc_buf_next_base_i : std_logic_vector(31 downto 0);
tdc_buf_next_size_size_i : std_logic_vector(29 downto 0);
tdc_buf_next_size_valid_i : std_logic;
end record;
constant c_TDC_BUF_in_registers_init_value: t_TDC_BUF_in_registers := (
tdc_buf_csr_done_i => '0',
tdc_buf_csr_overflow_i => '0',
tdc_buf_cur_base_i => (others => '0'),
tdc_buf_cur_count_i => (others => '0'),
tdc_buf_cur_size_size_i => (others => '0'),
tdc_buf_cur_size_valid_i => '0',
tdc_buf_next_base_i => (others => '0'),
tdc_buf_next_size_size_i => (others => '0'),
tdc_buf_next_size_valid_i => '0'
);
-- Output registers (WB slave -> user design)
type t_TDC_BUF_out_registers is record
tdc_buf_csr_enable_o : std_logic;
tdc_buf_csr_irq_timeout_o : std_logic_vector(9 downto 0);
tdc_buf_csr_burst_size_o : std_logic_vector(9 downto 0);
tdc_buf_csr_switch_buffers_o : std_logic;
tdc_buf_csr_done_o : std_logic;
tdc_buf_csr_done_load_o : std_logic;
tdc_buf_csr_overflow_o : std_logic;
tdc_buf_csr_overflow_load_o : std_logic;
tdc_buf_cur_base_o : std_logic_vector(31 downto 0);
tdc_buf_cur_base_load_o : std_logic;
tdc_buf_cur_size_size_o : std_logic_vector(29 downto 0);
tdc_buf_cur_size_size_load_o : std_logic;
tdc_buf_cur_size_valid_o : std_logic;
tdc_buf_cur_size_valid_load_o : std_logic;
tdc_buf_next_base_o : std_logic_vector(31 downto 0);
tdc_buf_next_base_load_o : std_logic;
tdc_buf_next_size_size_o : std_logic_vector(29 downto 0);
tdc_buf_next_size_size_load_o : std_logic;
tdc_buf_next_size_valid_o : std_logic;
tdc_buf_next_size_valid_load_o : std_logic;
end record;
constant c_TDC_BUF_out_registers_init_value: t_TDC_BUF_out_registers := (
tdc_buf_csr_enable_o => '0',
tdc_buf_csr_irq_timeout_o => (others => '0'),
tdc_buf_csr_burst_size_o => (others => '0'),
tdc_buf_csr_switch_buffers_o => '0',
tdc_buf_csr_done_o => '0',
tdc_buf_csr_done_load_o => '0',
tdc_buf_csr_overflow_o => '0',
tdc_buf_csr_overflow_load_o => '0',
tdc_buf_cur_base_o => (others => '0'),
tdc_buf_cur_base_load_o => '0',
tdc_buf_cur_size_size_o => (others => '0'),
tdc_buf_cur_size_size_load_o => '0',
tdc_buf_cur_size_valid_o => '0',
tdc_buf_cur_size_valid_load_o => '0',
tdc_buf_next_base_o => (others => '0'),
tdc_buf_next_base_load_o => '0',
tdc_buf_next_size_size_o => (others => '0'),
tdc_buf_next_size_size_load_o => '0',
tdc_buf_next_size_valid_o => '0',
tdc_buf_next_size_valid_load_o => '0'
);
function "or" (left, right: t_TDC_BUF_in_registers) return t_TDC_BUF_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component tdc_buffer_control_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_TDC_BUF_in_registers;
regs_o : out t_TDC_BUF_out_registers
);
end component;
end package;
package body TDC_BUF_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_TDC_BUF_in_registers) return t_TDC_BUF_in_registers is
variable tmp: t_TDC_BUF_in_registers;
begin
tmp.tdc_buf_csr_done_i := f_x_to_zero(left.tdc_buf_csr_done_i) or f_x_to_zero(right.tdc_buf_csr_done_i);
tmp.tdc_buf_csr_overflow_i := f_x_to_zero(left.tdc_buf_csr_overflow_i) or f_x_to_zero(right.tdc_buf_csr_overflow_i);
tmp.tdc_buf_cur_base_i := f_x_to_zero(left.tdc_buf_cur_base_i) or f_x_to_zero(right.tdc_buf_cur_base_i);
tmp.tdc_buf_cur_count_i := f_x_to_zero(left.tdc_buf_cur_count_i) or f_x_to_zero(right.tdc_buf_cur_count_i);
tmp.tdc_buf_cur_size_size_i := f_x_to_zero(left.tdc_buf_cur_size_size_i) or f_x_to_zero(right.tdc_buf_cur_size_size_i);
tmp.tdc_buf_cur_size_valid_i := f_x_to_zero(left.tdc_buf_cur_size_valid_i) or f_x_to_zero(right.tdc_buf_cur_size_valid_i);
tmp.tdc_buf_next_base_i := f_x_to_zero(left.tdc_buf_next_base_i) or f_x_to_zero(right.tdc_buf_next_base_i);
tmp.tdc_buf_next_size_size_i := f_x_to_zero(left.tdc_buf_next_size_size_i) or f_x_to_zero(right.tdc_buf_next_size_size_i);
tmp.tdc_buf_next_size_valid_i := f_x_to_zero(left.tdc_buf_next_size_valid_i) or f_x_to_zero(right.tdc_buf_next_size_valid_i);
return tmp;
end function;
end package body;
This diff is collapsed.
This diff is collapsed.
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC DMA Channel Control Registers
---------------------------------------------------------------------------------------
-- File : tdc_dma_channel_regs.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_dma_channel_regs.wb
-- Created : Wed Jul 18 23:25:00 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_dma_channel_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.TDMA_wbgen2_pkg.all;
entity tdc_dma_channel_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_TDMA_in_registers;
regs_o : out t_TDMA_out_registers
);
end tdc_dma_channel_wb;
architecture syn of tdc_dma_channel_wb is
signal tdma_csr_enable_int : std_logic ;
signal tdma_csr_irq_timeout_int : std_logic_vector(9 downto 0);
signal tdma_csr_burst_size_int : std_logic_vector(9 downto 0);
signal tdma_csr_switch_buffers_dly0 : std_logic ;
signal tdma_csr_switch_buffers_int : std_logic ;
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(2 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= slave_i.dat;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
tdma_csr_enable_int <= '0';
tdma_csr_irq_timeout_int <= "0000000000";
tdma_csr_burst_size_int <= "0000000000";
tdma_csr_switch_buffers_int <= '0';
regs_o.tdma_csr_done_load_o <= '0';
regs_o.tdma_csr_overflow_load_o <= '0';
regs_o.tdma_cur_base_load_o <= '0';
regs_o.tdma_cur_size_size_load_o <= '0';
regs_o.tdma_cur_size_valid_load_o <= '0';
regs_o.tdma_next_base_load_o <= '0';
regs_o.tdma_next_size_size_load_o <= '0';
regs_o.tdma_next_size_valid_load_o <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
tdma_csr_switch_buffers_int <= '0';
regs_o.tdma_csr_done_load_o <= '0';
regs_o.tdma_csr_overflow_load_o <= '0';
regs_o.tdma_cur_base_load_o <= '0';
regs_o.tdma_cur_size_size_load_o <= '0';
regs_o.tdma_cur_size_valid_load_o <= '0';
regs_o.tdma_next_base_load_o <= '0';
regs_o.tdma_next_size_size_load_o <= '0';
regs_o.tdma_next_size_valid_load_o <= '0';
ack_in_progress <= '0';
else
regs_o.tdma_csr_done_load_o <= '0';
regs_o.tdma_csr_overflow_load_o <= '0';
regs_o.tdma_cur_base_load_o <= '0';
regs_o.tdma_cur_size_size_load_o <= '0';
regs_o.tdma_cur_size_valid_load_o <= '0';
regs_o.tdma_next_base_load_o <= '0';
regs_o.tdma_next_size_size_load_o <= '0';
regs_o.tdma_next_size_valid_load_o <= '0';
end if;
else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
case rwaddr_reg(2 downto 0) is
when "000" =>
if (slave_i.we = '1') then
tdma_csr_enable_int <= wrdata_reg(0);
tdma_csr_irq_timeout_int <= wrdata_reg(10 downto 1);
tdma_csr_burst_size_int <= wrdata_reg(20 downto 11);
tdma_csr_switch_buffers_int <= wrdata_reg(21);
regs_o.tdma_csr_done_load_o <= '1';
regs_o.tdma_csr_overflow_load_o <= '1';
end if;
rddata_reg(0) <= tdma_csr_enable_int;
rddata_reg(10 downto 1) <= tdma_csr_irq_timeout_int;
rddata_reg(20 downto 11) <= tdma_csr_burst_size_int;
rddata_reg(21) <= '0';
rddata_reg(22) <= regs_i.tdma_csr_done_i;
rddata_reg(23) <= regs_i.tdma_csr_overflow_i;
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(2) <= '1';
ack_in_progress <= '1';
when "001" =>
if (slave_i.we = '1') then
regs_o.tdma_cur_base_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= regs_i.tdma_cur_base_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "010" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.tdma_cur_count_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "011" =>
if (slave_i.we = '1') then
regs_o.tdma_cur_size_size_load_o <= '1';
regs_o.tdma_cur_size_valid_load_o <= '1';
end if;
rddata_reg(29 downto 0) <= regs_i.tdma_cur_size_size_i;
rddata_reg(30) <= regs_i.tdma_cur_size_valid_i;
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "100" =>
if (slave_i.we = '1') then
regs_o.tdma_next_base_load_o <= '1';
end if;
rddata_reg(31 downto 0) <= regs_i.tdma_next_base_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "101" =>
if (slave_i.we = '1') then
regs_o.tdma_next_size_size_load_o <= '1';
regs_o.tdma_next_size_valid_load_o <= '1';
end if;
rddata_reg(29 downto 0) <= regs_i.tdma_next_size_size_i;
rddata_reg(30) <= regs_i.tdma_next_size_valid_i;
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
slave_o.dat <= rddata_reg;
-- Enable DMA
regs_o.tdma_csr_enable_o <= tdma_csr_enable_int;
-- IRQ Timeout (ms)
regs_o.tdma_csr_irq_timeout_o <= tdma_csr_irq_timeout_int;
-- Burst size (timestamps)
regs_o.tdma_csr_burst_size_o <= tdma_csr_burst_size_int;
-- Switch buffers
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
tdma_csr_switch_buffers_dly0 <= '0';
regs_o.tdma_csr_switch_buffers_o <= '0';
elsif rising_edge(clk_sys_i) then
tdma_csr_switch_buffers_dly0 <= tdma_csr_switch_buffers_int;
regs_o.tdma_csr_switch_buffers_o <= tdma_csr_switch_buffers_int and (not tdma_csr_switch_buffers_dly0);
end if;
end process;
-- DMA complete
regs_o.tdma_csr_done_o <= wrdata_reg(22);
-- DMA overflow
regs_o.tdma_csr_overflow_o <= wrdata_reg(23);
-- Base address
regs_o.tdma_cur_base_o <= wrdata_reg(31 downto 0);
-- Number of data samples in the buffer
-- Size (in transfers)
regs_o.tdma_cur_size_size_o <= wrdata_reg(29 downto 0);
-- Valid flag
regs_o.tdma_cur_size_valid_o <= wrdata_reg(30);
-- Base address
regs_o.tdma_next_base_o <= wrdata_reg(31 downto 0);
-- Size (in transfers)
regs_o.tdma_next_size_size_o <= wrdata_reg(29 downto 0);
-- Valid flag
regs_o.tdma_next_size_valid_o <= wrdata_reg(30);
rwaddr_reg <= slave_i.adr(4 downto 2);
slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc);
slave_o.err <= '0';
slave_o.rty <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o.ack <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC DMA Channel Control Registers
---------------------------------------------------------------------------------------
-- File : tdc_dma_channel_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_dma_channel_regs.wb
-- Created : Wed Jul 18 23:25:00 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_dma_channel_regs.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package TDMA_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_TDMA_in_registers is record
tdma_csr_done_i : std_logic;
tdma_csr_overflow_i : std_logic;
tdma_cur_base_i : std_logic_vector(31 downto 0);
tdma_cur_count_i : std_logic_vector(31 downto 0);
tdma_cur_size_size_i : std_logic_vector(29 downto 0);
tdma_cur_size_valid_i : std_logic;
tdma_next_base_i : std_logic_vector(31 downto 0);
tdma_next_size_size_i : std_logic_vector(29 downto 0);
tdma_next_size_valid_i : std_logic;
end record;
constant c_TDMA_in_registers_init_value: t_TDMA_in_registers := (
tdma_csr_done_i => '0',
tdma_csr_overflow_i => '0',
tdma_cur_base_i => (others => '0'),
tdma_cur_count_i => (others => '0'),
tdma_cur_size_size_i => (others => '0'),
tdma_cur_size_valid_i => '0',
tdma_next_base_i => (others => '0'),
tdma_next_size_size_i => (others => '0'),
tdma_next_size_valid_i => '0'
);
-- Output registers (WB slave -> user design)
type t_TDMA_out_registers is record
tdma_csr_enable_o : std_logic;
tdma_csr_irq_timeout_o : std_logic_vector(9 downto 0);
tdma_csr_burst_size_o : std_logic_vector(9 downto 0);
tdma_csr_switch_buffers_o : std_logic;
tdma_csr_done_o : std_logic;
tdma_csr_done_load_o : std_logic;
tdma_csr_overflow_o : std_logic;
tdma_csr_overflow_load_o : std_logic;
tdma_cur_base_o : std_logic_vector(31 downto 0);
tdma_cur_base_load_o : std_logic;
tdma_cur_size_size_o : std_logic_vector(29 downto 0);
tdma_cur_size_size_load_o : std_logic;
tdma_cur_size_valid_o : std_logic;
tdma_cur_size_valid_load_o : std_logic;
tdma_next_base_o : std_logic_vector(31 downto 0);
tdma_next_base_load_o : std_logic;
tdma_next_size_size_o : std_logic_vector(29 downto 0);
tdma_next_size_size_load_o : std_logic;
tdma_next_size_valid_o : std_logic;
tdma_next_size_valid_load_o : std_logic;
end record;
constant c_TDMA_out_registers_init_value: t_TDMA_out_registers := (
tdma_csr_enable_o => '0',
tdma_csr_irq_timeout_o => (others => '0'),
tdma_csr_burst_size_o => (others => '0'),
tdma_csr_switch_buffers_o => '0',
tdma_csr_done_o => '0',
tdma_csr_done_load_o => '0',
tdma_csr_overflow_o => '0',
tdma_csr_overflow_load_o => '0',
tdma_cur_base_o => (others => '0'),
tdma_cur_base_load_o => '0',
tdma_cur_size_size_o => (others => '0'),
tdma_cur_size_size_load_o => '0',
tdma_cur_size_valid_o => '0',
tdma_cur_size_valid_load_o => '0',
tdma_next_base_o => (others => '0'),
tdma_next_base_load_o => '0',
tdma_next_size_size_o => (others => '0'),
tdma_next_size_size_load_o => '0',
tdma_next_size_valid_o => '0',
tdma_next_size_valid_load_o => '0'
);
function "or" (left, right: t_TDMA_in_registers) return t_TDMA_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component tdc_dma_channel_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_TDMA_in_registers;
regs_o : out t_TDMA_out_registers
);
end component;
end package;
package body TDMA_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_TDMA_in_registers) return t_TDMA_in_registers is
variable tmp: t_TDMA_in_registers;
begin
tmp.tdma_csr_done_i := f_x_to_zero(left.tdma_csr_done_i) or f_x_to_zero(right.tdma_csr_done_i);
tmp.tdma_csr_overflow_i := f_x_to_zero(left.tdma_csr_overflow_i) or f_x_to_zero(right.tdma_csr_overflow_i);
tmp.tdma_cur_base_i := f_x_to_zero(left.tdma_cur_base_i) or f_x_to_zero(right.tdma_cur_base_i);
tmp.tdma_cur_count_i := f_x_to_zero(left.tdma_cur_count_i) or f_x_to_zero(right.tdma_cur_count_i);
tmp.tdma_cur_size_size_i := f_x_to_zero(left.tdma_cur_size_size_i) or f_x_to_zero(right.tdma_cur_size_size_i);
tmp.tdma_cur_size_valid_i := f_x_to_zero(left.tdma_cur_size_valid_i) or f_x_to_zero(right.tdma_cur_size_valid_i);
tmp.tdma_next_base_i := f_x_to_zero(left.tdma_next_base_i) or f_x_to_zero(right.tdma_next_base_i);
tmp.tdma_next_size_size_i := f_x_to_zero(left.tdma_next_size_size_i) or f_x_to_zero(right.tdma_next_size_size_i);
tmp.tdma_next_size_valid_i := f_x_to_zero(left.tdma_next_size_valid_i) or f_x_to_zero(right.tdma_next_size_valid_i);
return tmp;
end function;
end package body;
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.tdc_core_pkg.all;
use work.wishbone_pkg.all;
use work.genram_pkg.all;
use work.gencores_pkg.all;
entity tdc_dma_engine is
generic (
g_CLOCK_FREQ : integer := 62500000
);
port (
clk_i : in std_logic;
rst_n_i : in std_logic;
enable_i : in std_logic_vector(4 downto 0);
raw_mode_i : in std_logic_vector(4 downto 0);
ts_i : in t_tdc_timestamp_array(4 downto 0);
ts_valid_i : in std_logic_vector(4 downto 0);
ts_ready_o : out std_logic_vector(4 downto 0);
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
irq_o : out std_logic_vector(4 downto 0);
dma_wb_o : out t_wishbone_master_out;
dma_wb_i : in t_wishbone_master_in
);
end tdc_dma_engine;
architecture rtl of tdc_dma_engine is
signal cr_cnx_master_out : t_wishbone_master_out_array(4 downto 0);
signal cr_cnx_master_in : t_wishbone_master_in_array(4 downto 0);
signal dma_cnx_slave_out : t_wishbone_slave_out_array(4 downto 0);
signal dma_cnx_slave_in : t_wishbone_slave_in_array(4 downto 0);
signal c_CR_CNX_BASE_ADDR : t_wishbone_address_array(4 downto 0) :=
(0 => x"00000000",
1 => x"00000040",
2 => x"00000080",
3 => x"000000c0",
4 => x"00000100");
signal c_CR_CNX_BASE_MASK : t_wishbone_address_array(4 downto 0) :=
(0 => x"000001c0",
1 => x"000001c0",
2 => x"000001c0",
3 => x"000001c0",
4 => x"000001c0");
constant c_TIMER_PERIOD_MS : integer := 1;
constant c_TIMER_DIVIDER_VALUE : integer := g_CLOCK_FREQ * c_TIMER_PERIOD_MS / 1000 - 1;
signal irq_tick_div : unsigned(15 downto 0);
signal irq_tick : std_logic;
begin
p_irq_tick : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
irq_tick <= '0';
irq_tick_div <= (others => '0');
else
if irq_tick_div = c_TIMER_DIVIDER_VALUE then
irq_tick <= '1';
irq_tick_div <= (others => '0');
else
irq_tick <= '0';
irq_tick_div <= irq_tick_div + 1;
end if;
end if;
end if;
end process;
U_CR_Crossbar : xwb_crossbar
generic map (
g_num_masters => 1,
g_num_slaves => 5,
g_registered => true,
g_address => c_CR_CNX_BASE_ADDR,
g_mask => c_CR_CNX_BASE_MASK)
port map (
clk_sys_i => clk_i,
rst_n_i => rst_n_i,
slave_i(0) => slave_i,
slave_o(0) => slave_o,
master_i => cr_cnx_master_in,
master_o => cr_cnx_master_out);
U_DMA_Crossbar : xwb_crossbar
generic map (
g_num_masters => 5,
g_num_slaves => 1,
g_registered => true,
g_address => (0 => x"00000000"),
g_mask => (0 => x"00000000"))
port map (
clk_sys_i => clk_i,
rst_n_i => rst_n_i,
slave_i => dma_cnx_slave_in,
slave_o => dma_cnx_slave_out,
master_i(0) => dma_wb_i,
master_o(0) => dma_wb_o);
gen_channels : for i in 0 to 4 generate
U_DMA_Channel : entity work.tdc_dma_channel
generic map(
g_channel => i
)
port map (
clk_i => clk_i,
rst_n_i => rst_n_i,
enable_i => enable_i(i),
raw_mode_i => raw_mode_i(i),
ts_i => ts_i(i),
ts_valid_i => ts_valid_i(i),
ts_ready_o => ts_ready_o(i),
slave_i => cr_cnx_master_out(i),
slave_o => cr_cnx_master_in(i),
irq_o => irq_o(i),
irq_tick_i => irq_tick,
dma_wb_o => dma_cnx_slave_in(i),
dma_wb_i => dma_cnx_slave_out(i));
end generate gen_channels;
end rtl;
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : tdc_eic.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_eic.wb
-- Created : Mon Apr 20 17:34:12 2015
-- Created : Mon Aug 6 23:30:18 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_eic.wb
......@@ -19,7 +19,7 @@ entity tdc_eic is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 downto 0);
wb_adr_i : in std_logic_vector(3 downto 0);
wb_dat_i : in std_logic_vector(31 downto 0);
wb_dat_o : out std_logic_vector(31 downto 0);
wb_cyc_i : in std_logic;
......@@ -27,33 +27,40 @@ entity tdc_eic is
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_err_o : out std_logic;
wb_rty_o : out std_logic;
wb_stall_o : out std_logic;
wb_int_o : out std_logic;
irq_tdc_fifo1_i : in std_logic;
irq_tdc_fifo2_i : in std_logic;
irq_tdc_fifo3_i : in std_logic;
irq_tdc_fifo4_i : in std_logic;
irq_tdc_fifo5_i : in std_logic
irq_tdc_fifo5_i : in std_logic;
irq_tdc_dma1_i : in std_logic;
irq_tdc_dma2_i : in std_logic;
irq_tdc_dma3_i : in std_logic;
irq_tdc_dma4_i : in std_logic;
irq_tdc_dma5_i : in std_logic
);
end tdc_eic;
architecture syn of tdc_eic is
signal eic_idr_int : std_logic_vector(4 downto 0);
signal eic_idr_int : std_logic_vector(9 downto 0);
signal eic_idr_write_int : std_logic ;
signal eic_ier_int : std_logic_vector(4 downto 0);
signal eic_ier_int : std_logic_vector(9 downto 0);
signal eic_ier_write_int : std_logic ;
signal eic_imr_int : std_logic_vector(4 downto 0);
signal eic_isr_clear_int : std_logic_vector(4 downto 0);
signal eic_isr_status_int : std_logic_vector(4 downto 0);
signal eic_irq_ack_int : std_logic_vector(4 downto 0);
signal eic_imr_int : std_logic_vector(9 downto 0);
signal eic_isr_clear_int : std_logic_vector(9 downto 0);
signal eic_isr_status_int : std_logic_vector(9 downto 0);
signal eic_irq_ack_int : std_logic_vector(9 downto 0);
signal eic_isr_write_int : std_logic ;
signal irq_inputs_vector_int : std_logic_vector(4 downto 0);
signal irq_inputs_vector_int : std_logic_vector(9 downto 0);
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal rwaddr_reg : std_logic_vector(3 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
......@@ -61,13 +68,8 @@ signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments. For (foreseen) compatibility with other bus standards.
-- Some internal signals assignments
wrdata_reg <= wb_dat_i;
bwsel_reg <= wb_sel_i;
rd_int <= wb_cyc_i and (wb_stb_i and (not wb_we_i));
wr_int <= wb_cyc_i and (wb_stb_i and wb_we_i);
allones <= (others => '1');
allzeros <= (others => '0');
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
......@@ -93,8 +95,8 @@ begin
end if;
else
if ((wb_cyc_i = '1') and (wb_stb_i = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
case rwaddr_reg(3 downto 0) is
when "0000" =>
if (wb_we_i = '1') then
eic_idr_write_int <= '1';
end if;
......@@ -132,7 +134,7 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
when "0001" =>
if (wb_we_i = '1') then
eic_ier_write_int <= '1';
end if;
......@@ -170,15 +172,10 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
when "0010" =>
if (wb_we_i = '1') then
end if;
rddata_reg(4 downto 0) <= eic_imr_int(4 downto 0);
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(9 downto 0) <= eic_imr_int(9 downto 0);
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
......@@ -203,16 +200,11 @@ begin
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
when "0011" =>
if (wb_we_i = '1') then
eic_isr_write_int <= '1';
end if;
rddata_reg(4 downto 0) <= eic_isr_status_int(4 downto 0);
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(9 downto 0) <= eic_isr_status_int(9 downto 0);
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
......@@ -251,25 +243,25 @@ begin
-- Drive the data output bus
wb_dat_o <= rddata_reg;
-- extra code for reg/fifo/mem: Interrupt disable register
eic_idr_int(4 downto 0) <= wrdata_reg(4 downto 0);
eic_idr_int(9 downto 0) <= wrdata_reg(9 downto 0);
-- extra code for reg/fifo/mem: Interrupt enable register
eic_ier_int(4 downto 0) <= wrdata_reg(4 downto 0);
eic_ier_int(9 downto 0) <= wrdata_reg(9 downto 0);
-- extra code for reg/fifo/mem: Interrupt status register
eic_isr_clear_int(4 downto 0) <= wrdata_reg(4 downto 0);
eic_isr_clear_int(9 downto 0) <= wrdata_reg(9 downto 0);
-- extra code for reg/fifo/mem: IRQ_CONTROLLER
eic_irq_controller_inst : wbgen2_eic
eic_irq_controller_inst : entity work.wbgen2_eic_nomask
generic map (
g_num_interrupts => 5,
g_num_interrupts => 10,
g_irq00_mode => 3,
g_irq01_mode => 3,
g_irq02_mode => 3,
g_irq03_mode => 3,
g_irq04_mode => 3,
g_irq05_mode => 0,
g_irq06_mode => 0,
g_irq07_mode => 0,
g_irq08_mode => 0,
g_irq09_mode => 0,
g_irq05_mode => 3,
g_irq06_mode => 3,
g_irq07_mode => 3,
g_irq08_mode => 3,
g_irq09_mode => 3,
g_irq0a_mode => 0,
g_irq0b_mode => 0,
g_irq0c_mode => 0,
......@@ -314,8 +306,15 @@ begin
irq_inputs_vector_int(2) <= irq_tdc_fifo3_i;
irq_inputs_vector_int(3) <= irq_tdc_fifo4_i;
irq_inputs_vector_int(4) <= irq_tdc_fifo5_i;
irq_inputs_vector_int(5) <= irq_tdc_dma1_i;
irq_inputs_vector_int(6) <= irq_tdc_dma2_i;
irq_inputs_vector_int(7) <= irq_tdc_dma3_i;
irq_inputs_vector_int(8) <= irq_tdc_dma4_i;
irq_inputs_vector_int(9) <= irq_tdc_dma5_i;
rwaddr_reg <= wb_adr_i;
wb_stall_o <= (not ack_sreg(0)) and (wb_stb_i and wb_cyc_i);
wb_err_o <= '0';
wb_rty_o <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
wb_ack_o <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC Onewire Master
---------------------------------------------------------------------------------------
-- File : tdc_onewire_wb.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_onewire_wb.wb
-- Created : Tue Sep 11 11:16:49 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_onewire_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
use work.TDC_OW_wbgen2_pkg.all;
entity tdc_onewire_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_TDC_OW_in_registers;
regs_o : out t_TDC_OW_out_registers
);
end tdc_onewire_wb;
architecture syn of tdc_onewire_wb is
signal ack_sreg : std_logic_vector(9 downto 0);
signal rddata_reg : std_logic_vector(31 downto 0);
signal wrdata_reg : std_logic_vector(31 downto 0);
signal bwsel_reg : std_logic_vector(3 downto 0);
signal rwaddr_reg : std_logic_vector(1 downto 0);
signal ack_in_progress : std_logic ;
signal wr_int : std_logic ;
signal rd_int : std_logic ;
signal allones : std_logic_vector(31 downto 0);
signal allzeros : std_logic_vector(31 downto 0);
begin
-- Some internal signals assignments
wrdata_reg <= slave_i.dat;
--
-- Main register bank access process.
process (clk_sys_i, rst_n_i)
begin
if (rst_n_i = '0') then
ack_sreg <= "0000000000";
ack_in_progress <= '0';
rddata_reg <= "00000000000000000000000000000000";
regs_o.tdc_ow_csr_valid_load_o <= '0';
elsif rising_edge(clk_sys_i) then
-- advance the ACK generator shift register
ack_sreg(8 downto 0) <= ack_sreg(9 downto 1);
ack_sreg(9) <= '0';
if (ack_in_progress = '1') then
if (ack_sreg(0) = '1') then
regs_o.tdc_ow_csr_valid_load_o <= '0';
ack_in_progress <= '0';
else
regs_o.tdc_ow_csr_valid_load_o <= '0';
end if;
else
if ((slave_i.cyc = '1') and (slave_i.stb = '1')) then
case rwaddr_reg(1 downto 0) is
when "00" =>
if (slave_i.we = '1') then
regs_o.tdc_ow_csr_valid_load_o <= '1';
end if;
rddata_reg(0) <= regs_i.tdc_ow_csr_valid_i;
rddata_reg(1) <= 'X';
rddata_reg(2) <= 'X';
rddata_reg(3) <= 'X';
rddata_reg(4) <= 'X';
rddata_reg(5) <= 'X';
rddata_reg(6) <= 'X';
rddata_reg(7) <= 'X';
rddata_reg(8) <= 'X';
rddata_reg(9) <= 'X';
rddata_reg(10) <= 'X';
rddata_reg(11) <= 'X';
rddata_reg(12) <= 'X';
rddata_reg(13) <= 'X';
rddata_reg(14) <= 'X';
rddata_reg(15) <= 'X';
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "01" =>
if (slave_i.we = '1') then
end if;
rddata_reg(15 downto 0) <= regs_i.tdc_ow_temp_i;
rddata_reg(16) <= 'X';
rddata_reg(17) <= 'X';
rddata_reg(18) <= 'X';
rddata_reg(19) <= 'X';
rddata_reg(20) <= 'X';
rddata_reg(21) <= 'X';
rddata_reg(22) <= 'X';
rddata_reg(23) <= 'X';
rddata_reg(24) <= 'X';
rddata_reg(25) <= 'X';
rddata_reg(26) <= 'X';
rddata_reg(27) <= 'X';
rddata_reg(28) <= 'X';
rddata_reg(29) <= 'X';
rddata_reg(30) <= 'X';
rddata_reg(31) <= 'X';
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "10" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.tdc_ow_id_h_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when "11" =>
if (slave_i.we = '1') then
end if;
rddata_reg(31 downto 0) <= regs_i.tdc_ow_id_l_i;
ack_sreg(0) <= '1';
ack_in_progress <= '1';
when others =>
-- prevent the slave from hanging the bus on invalid address
ack_in_progress <= '1';
ack_sreg(0) <= '1';
end case;
end if;
end if;
end if;
end process;
-- Drive the data output bus
slave_o.dat <= rddata_reg;
-- Temperature & ID valid
regs_o.tdc_ow_csr_valid_o <= wrdata_reg(0);
-- Temperature
-- Unique ID (32 highest bits)
-- Unique ID (32 lowest bits)
rwaddr_reg <= slave_i.adr(3 downto 2);
slave_o.stall <= (not ack_sreg(0)) and (slave_i.stb and slave_i.cyc);
slave_o.err <= '0';
slave_o.rty <= '0';
-- ACK signal generation. Just pass the LSB of ACK counter.
slave_o.ack <= ack_sreg(0);
end syn;
---------------------------------------------------------------------------------------
-- Title : Wishbone slave core for TDC Onewire Master
---------------------------------------------------------------------------------------
-- File : tdc_onewire_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/tdc_onewire_wb.wb
-- Created : Tue Sep 11 11:16:49 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/tdc_onewire_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wishbone_pkg.all;
package TDC_OW_wbgen2_pkg is
-- Input registers (user design -> WB slave)
type t_TDC_OW_in_registers is record
tdc_ow_csr_valid_i : std_logic;
tdc_ow_temp_i : std_logic_vector(15 downto 0);
tdc_ow_id_h_i : std_logic_vector(31 downto 0);
tdc_ow_id_l_i : std_logic_vector(31 downto 0);
end record;
constant c_TDC_OW_in_registers_init_value: t_TDC_OW_in_registers := (
tdc_ow_csr_valid_i => '0',
tdc_ow_temp_i => (others => '0'),
tdc_ow_id_h_i => (others => '0'),
tdc_ow_id_l_i => (others => '0')
);
-- Output registers (WB slave -> user design)
type t_TDC_OW_out_registers is record
tdc_ow_csr_valid_o : std_logic;
tdc_ow_csr_valid_load_o : std_logic;
end record;
constant c_TDC_OW_out_registers_init_value: t_TDC_OW_out_registers := (
tdc_ow_csr_valid_o => '0',
tdc_ow_csr_valid_load_o => '0'
);
function "or" (left, right: t_TDC_OW_in_registers) return t_TDC_OW_in_registers;
function f_x_to_zero (x:std_logic) return std_logic;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector;
component tdc_onewire_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
slave_i : in t_wishbone_slave_in;
slave_o : out t_wishbone_slave_out;
int_o : out std_logic;
regs_i : in t_TDC_OW_in_registers;
regs_o : out t_TDC_OW_out_registers
);
end component;
end package;
package body TDC_OW_wbgen2_pkg is
function f_x_to_zero (x:std_logic) return std_logic is
begin
if x = '1' then
return '1';
else
return '0';
end if;
end function;
function f_x_to_zero (x:std_logic_vector) return std_logic_vector is
variable tmp: std_logic_vector(x'length-1 downto 0);
begin
for i in 0 to x'length-1 loop
if(x(i) = 'X' or x(i) = 'U') then
tmp(i):= '0';
else
tmp(i):=x(i);
end if;
end loop;
return tmp;
end function;
function "or" (left, right: t_TDC_OW_in_registers) return t_TDC_OW_in_registers is
variable tmp: t_TDC_OW_in_registers;
begin
tmp.tdc_ow_csr_valid_i := f_x_to_zero(left.tdc_ow_csr_valid_i) or f_x_to_zero(right.tdc_ow_csr_valid_i);
tmp.tdc_ow_temp_i := f_x_to_zero(left.tdc_ow_temp_i) or f_x_to_zero(right.tdc_ow_temp_i);
tmp.tdc_ow_id_h_i := f_x_to_zero(left.tdc_ow_id_h_i) or f_x_to_zero(right.tdc_ow_id_h_i);
tmp.tdc_ow_id_l_i := f_x_to_zero(left.tdc_ow_id_l_i) or f_x_to_zero(right.tdc_ow_id_l_i);
return tmp;
end function;
end package body;
-------------------------------------------------------------------------------
-- Title : Pipelined timestamp subtractor
-- Project : FMC TDC Core
-------------------------------------------------------------------------------
-- File : tdc_ts_sub.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 2018-09-10
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Pipelined timestamp adder with re-normalization of the result.
-- Adds a to b, producing normalized timestamp q. A timestmap is normalized when
-- the 0 <= frac < 2**g_frac_bits, 0 <= coarse <= g_coarse_range-1 and utc >= 0.
-- For correct operation of renormalizer, input timestamps must meet the
-- following constraints:
-- 1. 0 <= (a/b)_frac_i <= 2**g_frac_bits-1
-- 2. -g_coarse_range+1 <= (a_coarse_i + b_coarse_i) <= 3*g_coarse_range-1
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
-- 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
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.tdc_core_pkg.all;
entity tdc_ts_addsub is
generic(
g_frac_range : integer := 4096;
g_coarse_range : integer := 125000000
);
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
valid_i : in std_logic; -- when HI, a_* and b_* contain valid timestamps
enable_i : in std_logic := '1'; -- pipeline enable
a_i : in t_tdc_timestamp;
b_i : in t_tdc_timestamp;
valid_o : out std_logic;
q_o : out t_tdc_timestamp
);
end tdc_ts_addsub;
architecture rtl of tdc_ts_addsub is
constant c_NUM_PIPELINE_STAGES : integer := 4;
type t_internal_sum is record
tai : signed(32 downto 0);
coarse : signed(31 downto 0);
frac : signed(15 downto 0);
seq : std_logic_vector(31 downto 0);
meta : std_logic_vector(31 downto 0);
slope : std_logic;
end record;
type t_internal_sum_array is array (integer range <>) of t_internal_sum;
signal pipe : std_logic_vector(c_NUM_PIPELINE_STAGES-1 downto 0);
signal sums : t_internal_sum_array(0 to c_NUM_PIPELINE_STAGES-1);
signal ovf_frac : std_logic;
signal unf_frac : std_logic;
signal ovf_coarse : std_logic_vector(1 downto 0);
signal unf_coarse : std_logic_vector(1 downto 0);
begin -- rtl
-- Pipeline stage 0: just subtract the two timestamps field by field
p_stage0 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(0) <= '0';
elsif(enable_i = '1') then
pipe(0) <= valid_i;
sums(0).tai <= signed( resize(unsigned(a_i.tai) + unsigned(b_i.tai), 33) );
sums(0).seq <= a_i.seq;
sums(0).slope <= a_i.slope;
sums(0).meta <= a_i.meta;
sums(0).frac <= signed( resize(unsigned(a_i.frac),16) + resize(unsigned(b_i.frac), 16) );
sums(0).coarse <= signed(resize(unsigned(a_i.coarse), sums(0).coarse'length) +
resize(unsigned(b_i.coarse), sums(0).coarse'length));
else
pipe(0) <= '0';
end if;
end if;
end process;
unf_frac <= '1' when sums(0).frac < 0 else '0';
ovf_frac <= '1' when sums(0).frac >= g_frac_range else '0';
-- Pipeline stage 1: check the fractional difference for underflow and eventually adjust
-- the coarse difference
p_stage1 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(1) <= '0';
else
pipe(1) <= pipe(0);
sums(1).seq <= sums(0).seq;
sums(1).meta <= sums(0).meta;
sums(1).slope <= sums(0).slope;
if(ovf_frac = '1') then
sums(1).frac <= sums(0).frac - g_frac_range;
sums(1).coarse <= sums(0).coarse + 1;
elsif (unf_frac = '1') then
sums(1).frac <= sums(0).frac + g_frac_range;
sums(1).coarse <= sums(0).coarse - 1;
else
sums(1).frac <= sums(0).frac;
sums(1).coarse <= sums(0).coarse;
end if;
sums(1).tai <= sums(0).tai;
end if;
end if;
end process;
-- Pipeline stage 2: check the coarse sum for under/overflows
p_stage2 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(2) <= '0';
else
sums(2) <= sums(1);
pipe(2) <= pipe(1);
if(sums(1).coarse < 0) then
unf_coarse <= "10";
elsif(sums(1).coarse <= -g_coarse_range) then
unf_coarse <= "01";
else
unf_coarse <= "00";
end if;
if ( sums(1).coarse >= g_frac_range ) then
ovf_coarse <= "10";
elsif ( sums(1).coarse >= 2*g_frac_range ) then
ovf_coarse <= "01";
else
ovf_coarse <= "00";
end if;
end if;
end if;
end process;
-- Pipeline stage 3: adjust the coarse & TAI sums according to normalize the
-- previously detected under/overflows
p_stage3 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(3) <= '0';
else
pipe(3) <= pipe(2);
sums(3).seq <= sums(2).seq;
sums(3).slope <= sums(2).slope;
sums(3).meta <= sums(2).meta;
if(unf_coarse = "10") then
sums(3).coarse <= sums(2).coarse + g_coarse_range;
sums(3).tai <= sums(2).tai - 1;
elsif(unf_coarse = "01") then
sums(3).coarse <= sums(2).coarse + 2*g_coarse_range;
sums(3).tai <= sums(2).tai - 2;
elsif(ovf_coarse = "10" ) then
sums(3).coarse <= sums(2).coarse - g_coarse_range;
sums(3).tai <= sums(2).tai + 1;
elsif(ovf_coarse = "01") then
sums(3).coarse <= sums(2).coarse - 2*g_coarse_range;
sums(3).tai <= sums(2).tai + 2;
else
sums(3).coarse <= sums(2).coarse;
sums(3).tai <= sums(2).tai;
end if;
sums(3).frac <= sums(2).frac;
end if;
end if;
end process;
-- clip the extra bits and output the result
valid_o <= pipe(c_NUM_PIPELINE_STAGES-1);
q_o.tai <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).tai(31 downto 0));
q_o.coarse <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).coarse(31 downto 0));
q_o.frac <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).frac(11 downto 0));
q_o.seq <= sums(c_NUM_PIPELINE_STAGES-1).seq;
q_o.slope <= sums(c_NUM_PIPELINE_STAGES-1).slope;
q_o.meta <= sums(c_NUM_PIPELINE_STAGES-1).meta;
end rtl;
-------------------------------------------------------------------------------
-- Title : Pipelined timestamp subtractor
-- Project : FMC TDC Core
-------------------------------------------------------------------------------
-- File : tdc_ts_sub.vhd
-- Author : Tomasz Wlostowski
-- Company : CERN
-- Created : 2011-08-29
-- Last update: 2018-08-06
-- Platform : FPGA-generic
-- Standard : VHDL'93
-------------------------------------------------------------------------------
-- Description: Pipelined timestamp adder with re-normalization of the result.
-- Adds a to b, producing normalized timestamp q. A timestmap is normalized when
-- the 0 <= frac < 2**g_frac_bits, 0 <= coarse <= g_coarse_range-1 and utc >= 0.
-- For correct operation of renormalizer, input timestamps must meet the
-- following constraints:
-- 1. 0 <= (a/b)_frac_i <= 2**g_frac_bits-1
-- 2. -g_coarse_range+1 <= (a_coarse_i + b_coarse_i) <= 3*g_coarse_range-1
-------------------------------------------------------------------------------
--
-- Copyright (c) 2011 CERN / BE-CO-HT
-- 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
--
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.tdc_core_pkg.all;
entity tdc_ts_sub is
port(
clk_i : in std_logic;
rst_n_i : in std_logic;
valid_i : in std_logic; -- when HI, a_* and b_* contain valid timestamps
enable_i : in std_logic := '1'; -- pipeline enable
a_i : in t_tdc_timestamp;
b_i : in t_tdc_timestamp;
valid_o : out std_logic;
q_o : out t_tdc_timestamp
);
end tdc_ts_sub;
architecture rtl of tdc_ts_sub is
constant c_NUM_PIPELINE_STAGES : integer := 4;
constant c_frac_bits : integer := 12;
constant c_coarse_range : integer := 125000000;
type t_internal_sum is record
tai : signed(32 downto 0);
coarse : signed(31 downto 0);
frac : signed(15 downto 0);
end record;
type t_internal_sum_array is array (integer range <>) of t_internal_sum;
signal pipe : std_logic_vector(c_NUM_PIPELINE_STAGES-1 downto 0);
signal sums : t_internal_sum_array(0 to c_NUM_PIPELINE_STAGES-1);
signal ovf_frac : std_logic;
signal ovf_coarse : std_logic;
signal unf_coarse : std_logic_vector(1 downto 0);
begin -- rtl
-- Pipeline stage 0: just subtract the two timestamps field by field
p_stage0 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(0) <= '0';
elsif(enable_i = '1') then
pipe(0) <= valid_i;
sums(0).frac <= signed( resize(unsigned(a_i.frac) - unsigned(b_i.frac), 16) );
sums(0).coarse <= resize(signed(a_i.coarse), sums(0).coarse'length) -
resize(signed(b_i.coarse), sums(0).coarse'length);
sums(0).tai <= signed( resize(unsigned(a_i.tai) - unsigned(b_i.tai), 33) );
else
pipe(0) <= '0';
end if;
end if;
end process;
ovf_frac <= std_logic(sums(0).frac(sums(0).frac'length-1));
-- Pipeline stage 1: check the fractional difference for underflow and eventually adjust
-- the coarse difference
p_stage1 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(1) <= '0';
else
pipe(1) <= pipe(0);
if(ovf_frac = '1') then
sums(1).frac <= sums(0).frac + 2**c_frac_bits;
sums(1).coarse <= sums(0).coarse - 1;
else
sums(1).frac <= sums(0).frac;
sums(1).coarse <= sums(0).coarse;
end if;
sums(1).tai <= sums(0).tai;
end if;
end if;
end process;
-- Pipeline stage 2: check the coarse sum for under/overflows
p_stage2 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(2) <= '0';
else
sums(2) <= sums(1);
pipe(2) <= pipe(1);
if(sums(1).coarse < 0) then
unf_coarse <= "10";
elsif(sums(1).coarse <= -c_coarse_range) then
unf_coarse <= "01";
else
unf_coarse <= "00";
end if;
end if;
end if;
end process;
-- Pipeline stage 3: adjust the coarse & TAI sums according to normalize the
-- previously detected under/overflows
p_stage3 : process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_i = '0' then
pipe(3) <= '0';
else
pipe(3) <= pipe(2);
if(unf_coarse = "10") then
sums(3).coarse <= sums(2).coarse + c_coarse_range;
sums(3).tai <= sums(2).tai - 1;
elsif(unf_coarse = "01") then
sums(3).coarse <= sums(2).coarse + 2*c_coarse_range;
sums(3).tai <= sums(2).tai - 2;
else
sums(3).coarse <= sums(2).coarse;
sums(3).tai <= sums(2).tai;
end if;
sums(3).frac <= sums(2).frac;
end if;
end if;
end process;
-- clip the extra bits and output the result
valid_o <= pipe(c_NUM_PIPELINE_STAGES-1);
q_o.tai <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).tai(31 downto 0));
q_o.coarse <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).coarse(31 downto 0));
q_o.frac <= std_logic_vector(sums(c_NUM_PIPELINE_STAGES-1).frac(11 downto 0));
end rtl;
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
peripheral {
name = "GN4124 DMA enhanced interrupt controller";
description = "Enhanced interrrupt controller for GN4124 DMA.";
hdl_entity = "dma_eic";
prefix = "dma_eic";
irq {
name = "DMA done interrupt";
description = "DMA done interrupt line (rising edge sensitive).";
prefix = "dma_done";
trigger = EDGE_RISING;
};
irq {
name = "DMA error interrupt";
description = "DMA error interrupt line (rising edge sensitive).";
prefix = "dma_error";
trigger = EDGE_RISING;
};
};
This diff is collapsed.
......@@ -41,5 +41,40 @@ peripheral {
};
irq {
name = "FMC TDC timestamps interrupt (DMA1)";
description = "FMC TDC DMA1 acquisition ready.";
prefix = "tdc_dma1";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC timestamps interrupt (DMA2)";
description = "FMC TDC DMA1 acquisition ready.";
prefix = "tdc_dma2";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC timestamps interrupt (DMA3)";
description = "FMC TDC DMA3 acquisition ready.";
prefix = "tdc_dma3";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC timestamps interrupt (DMA4)";
description = "FMC TDC DMA4 acquisition ready.";
prefix = "tdc_dma4";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC timestamps interrupt (DMA5)";
description = "FMC TDC DMA5 acquisition ready.";
prefix = "tdc_dma5";
trigger = LEVEL_1;
};
};
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
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