Commit 0724de2e authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

wip

parent b10c63a4
......@@ -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 @ 50317193
Subproject commit 503171933f184ae878836f28e67a78a7c81b4325
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_sub.vhd",
"wbgen2_eic_nomask.vhd"
];
#!/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_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
......@@ -62,7 +62,7 @@
-- Standard library
library IEEE;
use IEEE.STD_LOGIC_1164.all; -- std_logic definitions
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
use IEEE.NUMERIC_STD.all; -- conversion functions-- Specific library
-- Specific library
library work;
use work.tdc_core_pkg.all; -- definitions of types, constants, entities
......@@ -101,7 +101,7 @@ entity data_formatting is
-- OUTPUTS
timestamp_o : out std_logic_vector(127 downto 0);
timestamp_o : out t_raw_acam_timestamp;
timestamp_valid_o : out std_logic
);
......@@ -137,7 +137,7 @@ architecture rtl of data_formatting is
signal un_current_retrig_from_roll_over : unsigned(31 downto 0);
signal un_acam_fine_time : unsigned(31 downto 0);
signal previous_utc : std_logic_vector(31 downto 0);
signal timestamp_valid_int : std_logic;
signal timestamp_valid_int : std_logic;
--=================================================================================================
-- architecture begin
......@@ -335,14 +335,24 @@ begin
full_timestamp(127 downto 96) <= metadata;
process(clk_i)
begin
if rising_edge(clk_i) then
timestamp_o <= full_timestamp;
timestamp_valid_o <= timestamp_valid_int;
if(timestamp_valid_int = '1') then
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;
timestamp_valid_o <= '1';
else
timestamp_valid_o <= '0';
end if;
end if;
end process;
end rtl;
----------------------------------------------------------------------------------------------------
-- architecture ends
......
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;
......@@ -366,23 +371,28 @@ begin
---------------------------------------------------------------------------------------------------
-- 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 +428,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,7 +451,11 @@ 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';
......
This diff is collapsed.
---------------------------------------------------------------------------------------
-- 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;
......@@ -60,6 +60,29 @@ use work.gencores_pkg.all;
--=================================================================================================
package tdc_core_pkg is
type t_raw_acam_timestamp is record
slope : std_logic;
channel : std_logic_vector(2 downto 0);
n_bins : std_logic_vector(16 downto 0);
coarse : std_logic_vector(31 downto 0);
tai : std_logic_vector(31 downto 0);
end record;
type t_tdc_timestamp is record
slope : std_logic;
channel : std_logic_vector(2 downto 0);
frac : std_logic_vector(11 downto 0);
coarse : std_logic_vector(31 downto 0);
tai : std_logic_vector(31 downto 0);
seq : std_logic_vector(31 downto 0);
end record;
constant c_dummy_timestamp : t_tdc_timestamp :=
( '0', "000", x"000", x"00000000", x"00000000", x"00000000" );
type t_tdc_timestamp_array is array(integer range<>) of t_tdc_timestamp;
---------------------------------------------------------------------------------------------------
-- Constant regarding the Mezzanine DAC configuration --
---------------------------------------------------------------------------------------------------
......@@ -187,6 +210,23 @@ package tdc_core_pkg is
name => "WB-TDC-TsFIFO ")));
constant c_TDC_DMA_SDB_DEVICE : t_sdb_device :=
(abi_class => x"0000", -- undocumented device
abi_ver_major => x"01",
abi_ver_minor => x"01",
wbd_endian => c_sdb_endian_big,
wbd_width => x"4", -- 32-bit port granularity
sdb_component =>
(addr_first => x"0000000000000000",
addr_last => x"00000000000001FF",
product =>
(vendor_id => x"000000000000CE42", -- CERN
device_id => x"00000623", -- "WB-TDC-Mem " | md5sum | cut -c1-8
version => x"00000001",
date => x"20150415",
name => "WB-TDC-TsDMAEngine ")));
---------------------------------------------------------------------------------------------------
-- Constants regarding 1 Hz pulse generation --
---------------------------------------------------------------------------------------------------
......@@ -396,12 +436,6 @@ package tdc_core_pkg is
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
-- Input pulses arriving also to the FPGA, currently not treated
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
-- White Rabbit core
wrabbit_link_up_i : in std_logic;
wrabbit_time_valid_i : in std_logic;
......@@ -470,11 +504,6 @@ package tdc_core_pkg is
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
wrabbit_status_reg_i : in std_logic_vector(g_width-1 downto 0);
wrabbit_ctrl_reg_o : out std_logic_vector(g_width-1 downto 0);
wrabbit_synched_i : in std_logic;
......@@ -482,7 +511,7 @@ package tdc_core_pkg is
wrabbit_tai_i : in std_logic_vector(31 downto 0);
cfg_slave_i : in t_wishbone_slave_in;
cfg_slave_o : out t_wishbone_slave_out;
timestamp_o : out std_logic_vector(127 downto 0);
timestamp_o : out t_tdc_timestamp;
timestamp_stb_o : out std_logic;
channel_enable_o : out std_logic_vector(4 downto 0);
irq_threshold_o : out std_logic_vector(9 downto 0);
......@@ -910,11 +939,6 @@ package tdc_core_pkg is
tdc_led_trig3_o : out std_logic;
tdc_led_trig4_o : out std_logic;
tdc_led_trig5_o : out std_logic;
tdc_in_fpga_1_i : in std_logic;
tdc_in_fpga_2_i : in std_logic;
tdc_in_fpga_3_i : in std_logic;
tdc_in_fpga_4_i : in std_logic;
tdc_in_fpga_5_i : in std_logic;
mezz_scl_o : out std_logic;
mezz_sda_o : out std_logic;
mezz_scl_i : in std_logic;
......@@ -936,6 +960,7 @@ package tdc_core_pkg is
irq_o : out std_logic;
clk_125m_tdc_o : out std_logic);
end component fmc_tdc_wrapper;
function f_pick(cond:boolean; if_true: std_logic_vector; if_false: std_logic_vector) return std_logic_vector;
......
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;
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
port map (
clk_i => clk_i,
rst_n_i => rst_n_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 : 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;
library ieee;
use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_STD.all;
use work.tdc_core_pkg.all;
use work.gencores_pkg.all;
entity timestamp_convert_filter is
port (
clk_tdc_i : in std_logic;
rst_tdc_n_i : in std_logic;
clk_sys_i : in std_logic;
rst_sys_n_i : in std_logic;
enable_i : in std_logic_vector(4 downto 0);
-- raw timestamp input, clk_tdc_i domain
ts_i : in t_raw_acam_timestamp;
ts_valid_i : in std_logic;
-- converted and filtered timestamp output, clk_sys_i domain
ts_o : out t_tdc_timestamp_array(4 downto 0);
ts_valid_o : out std_logic_vector(4 downto 0);
ts_ready_i : in std_logic_vector(4 downto 0)
);
end timestamp_convert_filter;
architecture rtl of timestamp_convert_filter is
constant c_MIN_PULSE_WIDTH_TICKS : integer := 12; -- 12 * 8 ns = 96 ns
constant c_FINE_SF : unsigned(17 downto 0) := to_unsigned(84934, 18);
constant c_FINE_SHIFT : integer := 11;
type t_channel_state is record
expected_edge : std_logic;
last_ts : t_tdc_timestamp;
last_valid : std_logic;
seq : unsigned(31 downto 0);
s1_delta_coarse : unsigned(31 downto 0);
s1_delta_tai : unsigned(31 downto 0);
s2_delta_coarse : unsigned(31 downto 0);
s2_delta_tai : unsigned(31 downto 0);
s1_valid, s2_valid : std_logic;
end record;
type t_channel_state_array is array(integer range<>) of t_channel_state;
signal channels : t_channel_state_array(0 to 4);
signal s1_frac_scaled : unsigned(31 downto 0);
signal s1_tai, s2_tai, s3_tai : unsigned(31 downto 0);
signal s1_valid, s2_valid, s3_valid : std_logic;
signal s1_coarse, s2_coarse, s3_coarse : unsigned(31 downto 0);
signal s2_frac, s3_frac : unsigned(11 downto 0);
signal coarse_adj : std_logic_vector(31 downto 0);
signal s1_channel, s2_channel, s3_channel : std_logic_vector(2 downto 0);
signal s1_edge, s2_edge, s3_edge : std_logic;
signal s3_ts : t_tdc_timestamp;
signal ts_valid_sys : std_logic;
begin
U_Sync_TS_Valid : gc_pulse_synchronizer2
port map (
clk_in_i => clk_tdc_i,
rst_in_n_i => rst_tdc_n_i,
clk_out_i => clk_sys_i,
rst_out_n_i => rst_sys_n_i,
d_ready_o => open,
d_p_i => ts_valid_i,
q_p_o => ts_valid_sys);
process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' then
s1_valid <= '0';
s2_valid <= '0';
s3_valid <= '0';
else
-- 64/125 = 4096/8000: reduce fraction to avoid 64-bit division
-- frac = hwts->bins * 81 * 64 / 125;
-- stage 1: scale frac
s1_frac_scaled <= resize ((unsigned(ts_i.n_bins) * c_FINE_SF) srl c_FINE_SHIFT, 32);
s1_coarse <= unsigned(ts_i.coarse);
s1_tai <= unsigned(ts_i.tai);
s1_edge <= ts_i.slope;
s1_channel <= ts_i.channel;
s1_valid <= ts_valid_sys;
-- stage 2: adjust coarse
s2_frac <= s1_frac_scaled(11 downto 0);
s2_coarse <= unsigned(s1_coarse) + s1_frac_scaled(31 downto 12);
s2_tai <= s1_tai;
s2_edge <= s1_edge;
s2_channel <= s1_channel;
s2_valid <= s1_valid;
-- stage 3: roll-over coarse
if s2_coarse(31) = '1' then
s3_coarse <= s2_coarse + to_unsigned(125000000, 32);
s3_tai <= s2_tai - 1;
elsif (s2_coarse >= 125000000) then
s3_coarse <= s2_coarse - to_unsigned(125000000, 32);
s3_tai <= s2_tai + 1;
else
s3_coarse <= s2_coarse;
s3_tai <= s2_tai;
end if;
s3_frac <= s2_frac;
s3_edge <= s2_edge;
s3_channel <= s2_channel;
s3_valid <= s2_valid;
end if;
end if;
end process;
s3_ts.frac <= std_logic_vector(s3_frac);
s3_ts.coarse <= std_logic_vector(s3_coarse);
s3_ts.tai <= std_logic_vector(s3_tai);
s3_ts.slope <= s3_edge;
s3_ts.channel <= s3_channel;
gen_channels : for i in 0 to 4 generate
p_fsm : process(clk_sys_i)
begin
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i(i) = '0' then
ts_valid_o(i) <= '0';
channels(i).expected_edge <= '1';
channels(i).s1_valid <= '0';
channels(i).s2_valid <= '0';
channels(i).last_valid <= '0';
channels(i).seq <= (others => '0');
else
channels(i).s1_valid <= '0';
if s3_valid = '1' and unsigned(s3_channel) = i then
-- report "s3_valid";
if (s3_ts.slope = '1') then -- rising edge
channels(i).last_ts <= s3_ts;
channels(i).last_valid <= '1';
channels(i).s1_valid <= '0';
-- report "rise";
else
channels(i).last_valid <= '0';
channels(i).s1_valid <= '1';
-- report "fall";
end if;
channels(i).s1_delta_coarse <= unsigned(s3_ts.coarse) - unsigned(channels(i).last_ts.coarse);
channels(i).s1_delta_tai <= unsigned(s3_ts.tai) - unsigned(channels(i).last_ts.tai);
end if;
if channels(i).s1_delta_coarse(31) = '1' then
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse + to_unsigned(125000000, 32);
channels(i).s2_delta_tai <= channels(i).s1_delta_tai - 1;
else
channels(i).s2_delta_coarse <= channels(i).s1_delta_coarse;
channels(i).s2_delta_tai <= channels(i).s1_delta_tai;
end if;
channels(i).s2_valid <= channels(i).s1_valid;
if(ts_ready_i(i) = '1') then
ts_valid_o(i) <= '0';
end if;
if channels(i).s2_valid = '1' then
if channels(i).s2_delta_tai = 0 and channels(i).s2_delta_coarse >= 12 then
ts_o(i).tai <= channels(i).last_ts.tai;
ts_o(i).coarse <= channels(i).last_ts.coarse;
ts_o(i).frac <= channels(i).last_ts.frac;
ts_o(i).channel <= channels(i).last_ts.channel;
ts_o(i).slope <= channels(i).last_ts.slope;
ts_o(i).seq <= std_logic_vector(channels(i).seq);
ts_valid_o(i) <= '1';
channels(i).seq <= channels(i).seq + 1;
end if;
end if;
end if;
end if;
end process;
end generate gen_channels;
--edge = hwts->metadata & (1 << 4) ? 1 : 0;
-- /* first, convert the timestamp from the HDL units (81 ps bins)
-- to the WR format (where fractional part is 8 ns rescaled to
-- 4096 units) */
-- ts.channel = channel + 1; /* We want to see channels starting from 1*/
-- ts.seconds = hwts->utc;
-- /* 64/125 = 4096/8000: reduce fraction to avoid 64-bit division */
-- frac = hwts->bins * 81 * 64 / 125;
-- ts.coarse = hwts->coarse + frac / 4096;
-- ts.frac = frac % 4096;
-- /* the addition above may result with the coarse counter going
-- out of range: */
-- if (unlikely(ts.coarse >= 125000000)) {
-- ts.coarse -= 125000000;
-- ts.seconds++;
-- }
-- /* A trivial state machine to remove glitches, react on rising edge only
-- and drop pulses that are narrower than 100 ns.
-- We are waiting for a falling edge,
-- but a rising one occurs - ignore it.
-- */
-- if (unlikely(edge != st->expected_edge)) {
-- /* wait unconditionally for next rising edge */
-- st->expected_edge = 1;
-- return 0;
-- }
-- /* From this point we are working with the expected EDGE */
-- if (st->expected_edge == 1) {
-- /* We received a raising edge, save the time stamp and
-- wait for the falling edge */
-- st->prev_ts = ts;
-- st->expected_edge = 0;
-- return 0;
-- }
-- /* got a falling edge after a rising one */
-- diff = ts;
-- ft_ts_sub(&diff, &st->prev_ts);
-- /* Check timestamp width. Must be at least 100 ns
-- (coarse = 12, frac = 2048) */
-- if (likely(diff.seconds || diff.coarse > 12
-- || (diff.coarse == 12 && diff.frac >= 2048))) {
-- ts = st->prev_ts;
-- ft_ts_apply_offset(&ts, ft->calib.zero_offset[channel - 1]);
-- ft_ts_apply_offset(&ts, -ft->calib.wr_offset);
-- if (st->user_offset)
-- ft_ts_apply_offset(&ts, st->user_offset);
-- ts.gseq_id = ft->sequence++;
-- /* Got a dacapo flag? make a gap in the sequence ID to indicate
-- an unknown loss of timestamps */
-- ts.dseq_id = st->cur_seq_id++;
-- if (dacapo_flag) {
-- ts.dseq_id++;
-- st->cur_seq_id++;
-- }
-- ts.hseq_id = hwts->metadata >> 5;
-- /* Return a valid timestamp */
-- *wrts = ts;
-- ret = 1;
-- }
-- /* Wait for the next raising edge */
-- st->expected_edge = 1;
end rtl;
......@@ -23,6 +23,7 @@ use ieee.std_logic_1164.all;
use ieee.NUMERIC_STD.all;
use work.tsf_wbgen2_pkg.all;
use work.tdc_core_pkg.all;
use work.wishbone_pkg.all;
use work.gencores_pkg.all;
......@@ -32,9 +33,7 @@ entity timestamp_fifo is
);
port (
clk_sys_i : in std_logic;
clk_tdc_i : in std_logic;
rst_n_sys_i : in std_logic;
rst_tdc_i : in std_logic;
rst_sys_n_i : in std_logic;
-- WB slave, system clock
slave_i : in t_wishbone_slave_in;
......@@ -45,36 +44,17 @@ entity timestamp_fifo is
enable_i : in std_logic; -- channel enable, TDC clock
tick_i : in std_logic; -- 1ms tick, TDC clock
irq_threshold_i : in std_logic_vector(9 downto 0);
irq_timeout_i : in std_logic_vector(9 downto 0);
irq_timeout_i : in std_logic_vector(9 downto 0);
timestamp_i : in std_logic_vector(127 downto 0);
timestamp_valid_i : in std_logic
timestamp_i : in t_tdc_timestamp_array(4 downto 0);
timestamp_valid_i : in std_logic_vector(4 downto 0)
);
end entity;
architecture rtl of timestamp_fifo is
component timestamp_fifo_wb is
port (
rst_n_i : in std_logic;
clk_sys_i : in std_logic;
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;
wb_sel_i : in std_logic_vector(3 downto 0);
wb_stb_i : in std_logic;
wb_we_i : in std_logic;
wb_ack_o : out std_logic;
wb_stall_o : out std_logic;
clk_tdc_i : in std_logic;
regs_i : in t_tsf_in_registers;
regs_o : out t_tsf_out_registers);
end component timestamp_fifo_wb;
signal tmr_timeout : unsigned(9 downto 0);
signal buf_irq_int : std_logic;
signal buf_count : unsigned(9 downto 0);
......@@ -86,44 +66,45 @@ architecture rtl of timestamp_fifo is
signal ts_match : std_logic;
signal seq_counter : unsigned(31 downto 0);
signal timestamp_with_seq : std_logic_vector(127 downto 0);
signal ref_valid : std_logic;
signal ref_ts : t_tdc_timestamp;
signal ref_channel : integer range 0 to 4;
signal sub_valid : std_logic;
signal sub_in_valid, sub_out_valid : std_logic;
signal sub_result : t_tdc_timestamp;
begin
timestamp_with_seq(95 downto 0) <= timestamp_i(95 downto 0); -- TS
timestamp_with_seq(98 downto 96) <= timestamp_i(98 downto 96); -- channel
timestamp_with_seq(100) <= timestamp_i(100); -- slope
timestamp_with_seq(127 downto 101) <= std_logic_vector(seq_counter(26 downto 0));
U_WB_Slave : timestamp_fifo_wb
timestamp_with_seq(31 downto 0) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).tai), 32));
timestamp_with_seq(63 downto 32) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).coarse), 32));
timestamp_with_seq(95 downto 64) <= std_logic_vector(resize(unsigned(timestamp_i(g_channel).frac), 32));
timestamp_with_seq(98 downto 96) <= timestamp_i(g_channel).channel;
timestamp_with_seq(99) <= timestamp_i(g_channel).slope;
timestamp_with_seq(127 downto 100) <= timestamp_i(g_channel).seq(27 downto 0);
U_WB_Slave : entity work.timestamp_fifo_wb
port map (
rst_n_i => rst_n_sys_i,
clk_sys_i => clk_sys_i,
wb_adr_i => slave_i.adr(5 downto 2),
wb_dat_i => slave_i.dat,
wb_dat_o => slave_o.dat,
wb_cyc_i => slave_i.cyc,
wb_sel_i => slave_i.sel,
wb_stb_i => slave_i.stb,
wb_we_i => slave_i.we,
wb_ack_o => slave_o.ack,
wb_stall_o => slave_o.stall,
clk_tdc_i => clk_tdc_i,
regs_i => regs_in,
regs_o => regs_out);
rst_n_i => rst_sys_n_i,
clk_sys_i => clk_sys_i,
slave_i => slave_i,
slave_o => slave_o,
regs_i => regs_in,
regs_o => regs_out);
buf_count <= resize(unsigned(regs_out.fifo_wr_usedw_o), 10);
ts_match <= '1' when timestamp_valid_i = '1' and unsigned(timestamp_i(98 downto 96)) = g_channel else '0';
p_fifo_write : process(clk_tdc_i)
ts_match <= timestamp_valid_i(g_channel);
p_fifo_write : process(clk_sys_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_i = '1' then
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' then
regs_in.fifo_wr_req_i <= '0';
else
if(enable_i = '1' and regs_out.fifo_wr_full_o = '0' and ts_match = '1') then
regs_in.fifo_wr_req_i <= '1';
else
......@@ -138,47 +119,38 @@ begin
regs_in.fifo_ts2_i <= timestamp_with_seq(95 downto 64);
regs_in.fifo_ts3_i <= timestamp_with_seq(127 downto 96);
p_seq_counter : process(clk_tdc_i)
p_latch_ref_timestamp : process(clk_sys_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_i = '1' or regs_out.csr_rst_seq_o = '1' then
seq_counter <= (others => '0');
else
if(enable_i = '1' and ts_match = '1') then
seq_counter <= seq_counter + 1;
end if;
end if;
end if;
end process;
p_latch_last_timestamp : process(clk_tdc_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_i = '1' then
regs_in.csr_last_valid_i <= '0';
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i = '0' then
ref_valid <= '0';
else
-- latch only the last rising edge TS
if (enable_i = '1' and ts_match = '1' and timestamp_with_seq(100) = '1') then
regs_in.csr_last_valid_i <= '1';
last_ts <= timestamp_with_seq;
elsif (regs_out.csr_last_valid_o = '0' and regs_out.csr_last_valid_load_o = '1') then
regs_in.csr_last_valid_i <= '0';
end if;
if (regs_out.csr_last_valid_o = '0' and regs_out.csr_last_valid_load_o = '1') then
regs_in.lts0_i <= last_ts(31 downto 0);
regs_in.lts1_i <= last_ts(63 downto 32);
regs_in.lts2_i <= last_ts(95 downto 64);
regs_in.lts3_i <= last_ts(127 downto 96);
if (enable_i = '1' and timestamp_valid_i(ref_channel) = '1') then
ref_valid <= '1';
ref_ts <= timestamp_i(ref_channel);
end if;
end if;
end if;
end process;
p_coalesce_irq : process(clk_tdc_i)
sub_valid <= ref_valid and ts_match;
U_Subtractor: entity work.tdc_ts_sub
port map (
clk_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
valid_i => sub_in_valid,
enable_i => enable_i,
a_i => timestamp_i(g_channel),
b_i => ref_ts,
valid_o => sub_out_valid,
q_o => sub_result);
p_coalesce_irq : process(clk_sys_i)
begin
if rising_edge(clk_tdc_i) then
if rst_tdc_i = '1' or enable_i = '0' then
if rising_edge(clk_sys_i) then
if rst_sys_n_i = '0' or enable_i = '0' then
buf_irq_int <= '0';
else
if(regs_out.fifo_wr_empty_o = '1') then
......@@ -209,11 +181,6 @@ begin
end if;
end process;
U_Sync_IRQ : gc_sync_ffs
port map (
clk_i => clk_sys_i,
rst_n_i => rst_n_sys_i,
data_i => buf_irq_int,
synced_o => irq_o);
irq_o <= buf_irq_int;
end rtl;
This diff is collapsed.
......@@ -3,7 +3,7 @@
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created : Wed Sep 20 18:41:08 2017
-- Created : Mon Aug 6 23:30:18 2018
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
......@@ -14,6 +14,7 @@ library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use work.wbgen2_pkg.all;
use work.wishbone_pkg.all;
package tsf_wbgen2_pkg is
......@@ -26,12 +27,12 @@ package tsf_wbgen2_pkg is
fifo_ts1_i : std_logic_vector(31 downto 0);
fifo_ts2_i : std_logic_vector(31 downto 0);
fifo_ts3_i : std_logic_vector(31 downto 0);
lts0_i : std_logic_vector(31 downto 0);
lts1_i : std_logic_vector(31 downto 0);
lts2_i : std_logic_vector(31 downto 0);
lts3_i : std_logic_vector(31 downto 0);
csr_last_valid_i : std_logic;
end record;
delta0_i : std_logic_vector(31 downto 0);
delta1_i : std_logic_vector(31 downto 0);
delta2_i : std_logic_vector(31 downto 0);
delta3_i : std_logic_vector(31 downto 0);
csr_delta_valid_i : std_logic;
end record;
constant c_tsf_in_registers_init_value: t_tsf_in_registers := (
fifo_wr_req_i => '0',
......@@ -39,71 +40,90 @@ package tsf_wbgen2_pkg is
fifo_ts1_i => (others => '0'),
fifo_ts2_i => (others => '0'),
fifo_ts3_i => (others => '0'),
lts0_i => (others => '0'),
lts1_i => (others => '0'),
lts2_i => (others => '0'),
lts3_i => (others => '0'),
csr_last_valid_i => '0'
);
-- Output registers (WB slave -> user design)
type t_tsf_out_registers is record
fifo_wr_full_o : std_logic;
fifo_wr_empty_o : std_logic;
fifo_wr_usedw_o : std_logic_vector(8 downto 0);
csr_last_valid_o : std_logic;
csr_last_valid_load_o : std_logic;
csr_rst_seq_o : std_logic;
end record;
constant c_tsf_out_registers_init_value: t_tsf_out_registers := (
fifo_wr_full_o => '0',
fifo_wr_empty_o => '0',
fifo_wr_usedw_o => (others => '0'),
csr_last_valid_o => '0',
csr_last_valid_load_o => '0',
csr_rst_seq_o => '0'
);
function "or" (left, right: t_tsf_in_registers) return t_tsf_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;
delta0_i => (others => '0'),
delta1_i => (others => '0'),
delta2_i => (others => '0'),
delta3_i => (others => '0'),
csr_delta_valid_i => '0'
);
-- Output registers (WB slave -> user design)
type t_tsf_out_registers is record
fifo_wr_full_o : std_logic;
fifo_wr_empty_o : std_logic;
fifo_wr_usedw_o : std_logic_vector(5 downto 0);
csr_delta_valid_o : std_logic;
csr_delta_valid_load_o : std_logic;
csr_rst_seq_o : std_logic;
csr_delta_ref_o : std_logic_vector(2 downto 0);
end record;
constant c_tsf_out_registers_init_value: t_tsf_out_registers := (
fifo_wr_full_o => '0',
fifo_wr_empty_o => '0',
fifo_wr_usedw_o => (others => '0'),
csr_delta_valid_o => '0',
csr_delta_valid_load_o => '0',
csr_rst_seq_o => '0',
csr_delta_ref_o => (others => '0')
);
function "or" (left, right: t_tsf_in_registers) return t_tsf_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 timestamp_fifo_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_tsf_in_registers;
regs_o : out t_tsf_out_registers
);
end component;
end package;
package body tsf_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;
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);
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;
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_tsf_in_registers) return t_tsf_in_registers is
variable tmp: t_tsf_in_registers;
variable tmp: t_tsf_in_registers;
begin
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i);
tmp.fifo_ts0_i := f_x_to_zero(left.fifo_ts0_i) or f_x_to_zero(right.fifo_ts0_i);
tmp.fifo_ts1_i := f_x_to_zero(left.fifo_ts1_i) or f_x_to_zero(right.fifo_ts1_i);
tmp.fifo_ts2_i := f_x_to_zero(left.fifo_ts2_i) or f_x_to_zero(right.fifo_ts2_i);
tmp.fifo_ts3_i := f_x_to_zero(left.fifo_ts3_i) or f_x_to_zero(right.fifo_ts3_i);
tmp.lts0_i := f_x_to_zero(left.lts0_i) or f_x_to_zero(right.lts0_i);
tmp.lts1_i := f_x_to_zero(left.lts1_i) or f_x_to_zero(right.lts1_i);
tmp.lts2_i := f_x_to_zero(left.lts2_i) or f_x_to_zero(right.lts2_i);
tmp.lts3_i := f_x_to_zero(left.lts3_i) or f_x_to_zero(right.lts3_i);
tmp.csr_last_valid_i := f_x_to_zero(left.csr_last_valid_i) or f_x_to_zero(right.csr_last_valid_i);
return tmp;
tmp.fifo_wr_req_i := f_x_to_zero(left.fifo_wr_req_i) or f_x_to_zero(right.fifo_wr_req_i);
tmp.fifo_ts0_i := f_x_to_zero(left.fifo_ts0_i) or f_x_to_zero(right.fifo_ts0_i);
tmp.fifo_ts1_i := f_x_to_zero(left.fifo_ts1_i) or f_x_to_zero(right.fifo_ts1_i);
tmp.fifo_ts2_i := f_x_to_zero(left.fifo_ts2_i) or f_x_to_zero(right.fifo_ts2_i);
tmp.fifo_ts3_i := f_x_to_zero(left.fifo_ts3_i) or f_x_to_zero(right.fifo_ts3_i);
tmp.delta0_i := f_x_to_zero(left.delta0_i) or f_x_to_zero(right.delta0_i);
tmp.delta1_i := f_x_to_zero(left.delta1_i) or f_x_to_zero(right.delta1_i);
tmp.delta2_i := f_x_to_zero(left.delta2_i) or f_x_to_zero(right.delta2_i);
tmp.delta3_i := f_x_to_zero(left.delta3_i) or f_x_to_zero(right.delta3_i);
tmp.csr_delta_valid_i := f_x_to_zero(left.csr_delta_valid_i) or f_x_to_zero(right.csr_delta_valid_i);
return tmp;
end function;
end package body;
-- -*- Mode: LUA; tab-width: 2 -*-
peripheral {
name = "TDC DMA Buffer Control Registers";
prefix="TDC_BUF";
hdl_entity="tdc_buffer_control_wb";
reg {
name = "Control/Status register";
prefix = "CSR";
field {
name = "Enable acquisition";
description = "1: timestamps of the given channel will be sequentially written to the current buffer, provided it's valid (CUR_SIZE.VALID=1) \
0: acquisition off";
prefix = "ENABLE";
type = BIT;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
field {
name = "IRQ Timeout (ms)";
prefix = "IRQ_TIMEOUT";
description = "Interrupt coalescing timeout in milliseconds. Pick a high enough value to avoid too frequent interrupts and a low enough one to prevent buffer contention. 10 ms should be OK for most of the cases";
size = 10;
type = SLV;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
field {
name = "Burst size (timestamps)";
prefix = "BURST_SIZE";
description = "Number of timestamps in a single burst to the DDR memory. Default = 16";
size = 10;
type = SLV;
access_dev = READ_ONLY;
access_bus = READ_WRITE;
};
field {
name = "Switch buffers";
description = "write 1: atomically switches the acquisition buffer from the current one (base/size in CUR_BASE/CUR_SIZE) to the next one (described in NEXT_BASE/NEXT_SIZE registers)\
write 0: no action";
prefix = "SWITCH_BUFFERS";
type = MONOSTABLE;
};
field {
name = "Burst complete";
prefix = "DONE";
description = "read 1: the current buffer has been fully committed to the DDR memory after writing 1 to SWITCH_BUFFERS field.\
read 0: still some transfers pending";
type = BIT;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "DMA overflow";
prefix = "OVERFLOW";
description = "read 1: both the current and the next buffer have been filled with timestamps. Dropping all new incoming TS.";
type = BIT;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Current buffer base address register";
prefix = "CUR_BASE";
field {
name = "Base address";
description = "Base address of the current buffer (in bytes) relative to the DDR3 chip (0 = first word in the memory)";
size = 32;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Current buffer base count register";
prefix = "CUR_COUNT";
field {
name = "Number of data samples";
description="Number of data samples in the buffer (1 sample = 1 timestamp)";
size = 32;
type = SLV;
access_dev = WRITE_ONLY;
access_bus = READ_ONLY;
};
};
reg {
name = "Current buffer base size/valid flag register";
prefix = "CUR_SIZE";
field {
name = "Size";
description="Number of data samples the buffer can hold (1 sample = 1 timestamp)";
prefix = "SIZE";
size = 30;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Valid flag";
prefix = "VALID";
description="write 1: indicate that this buffer is ready for acquisition and correctly configured";
size = 30;
type = BIT;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Next buffer base address register";
prefix = "NEXT_BASE";
field {
name = "Base address";
size = 32;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
reg {
name = "Next buffer base size/valid flag register";
prefix = "NEXT_SIZE";
field {
name = "Size (in transfers)";
prefix = "SIZE";
size = 30;
type = SLV;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Valid flag";
prefix = "VALID";
size = 30;
type = BIT;
access_dev = READ_WRITE;
access_bus = READ_WRITE;
load = LOAD_EXT;
};
};
};
......@@ -40,6 +40,41 @@ peripheral {
trigger = LEVEL_1;
};
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;
};
};
......@@ -9,11 +9,10 @@ peripheral {
-- TXTSU shared FIFO
fifo_reg {
size = 512; -- or more. We'll see :)
size = 64; -- or more. We'll see :)
direction = CORE_TO_BUS;
prefix = "fifo";
name = "Timestamp FIFO";
clock = "clk_tdc_i";
flags_bus = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT, FIFO_CLEAR};
flags_dev = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
......@@ -40,7 +39,7 @@ peripheral {
};
field {
name = "The timestamp (word 4)";
name = "The timestamp (word 3)";
prefix = "ts3";
type = SLV;
size = 32;
......@@ -49,12 +48,11 @@ peripheral {
reg {
name = "Last Timestamp Word 0";
prefix = "LTS0";
name = "Delta Timestamp word 0";
prefix = "DELTA0";
field {
name = "Last Timestamp Word 0";
clock = "clk_tdc_i";
name = "Delta Timestamp Word 0";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -63,12 +61,11 @@ peripheral {
};
};
reg {
name = "Last Timestamp Word 1";
prefix = "LTS1";
name = "Delta Timestamp Word 1";
prefix = "DELTA1";
field {
name = "Last Timestamp Word 1";
clock = "clk_tdc_i";
name = "Delta Timestamp Word 1";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -77,12 +74,11 @@ peripheral {
};
reg {
name = "Last Timestamp Word 2";
prefix = "LTS2";
name = "Delta Timestamp Word 2";
prefix = "DELTA2";
field {
name = "Last Timestamp Word 2";
clock = "clk_tdc_i";
name = "Delta Timestamp Word 2";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -92,12 +88,11 @@ peripheral {
};
reg {
name = "Last Timestamp Word 3";
prefix = "LTS3";
name = "Delta Timestamp Word 3";
prefix = "DELTA3";
field {
name = "Last Timestamp Word 3";
clock = "clk_tdc_i";
name = "Delta Timestamp Word 3";
type = SLV;
size = 32;
access_bus = READ_ONLY;
......@@ -113,9 +108,8 @@ peripheral {
prefix = "CSR";
field {
name = "Last Timestamp Valid";
clock = "clk_tdc_i";
prefix = "LAST_VALID";
name = "Delta Timestamp Valid";
prefix = "DELTA_VALID";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
......@@ -124,11 +118,20 @@ peripheral {
field {
name = "Reset Sequence Counter";
clock = "clk_tdc_i";
prefix = "RST_SEQ";
type = MONOSTABLE;
};
field {
name = "Delta Timestamp Reference Channel";
description = "Channel (0-4) to take as the reference for the delta timestamps";
prefix = "DELTA_REF";
type = SLV;
size = 3;
access_bus = READ_WRITE;
access_dev = READ_ONLY;
};
};
......
This diff is collapsed.
This diff is collapsed.
......@@ -12,3 +12,4 @@ syn_tool = "ise"
top_module = "wr_spec_tdc"
modules = { "local" : [ "../../top/spec" ] }
ctrls = ["bank3_32b_32b"]
This diff is collapsed.
`include "simdrv_defs.svh"
`include "if_wb_master.svh"
`include "if_wb_slave.svh"
interface IVHDWishboneMaster
(
......@@ -57,3 +58,60 @@ interface IVHDWishboneMaster
endinterface // IVHDWishboneMaster
interface IVHDWishboneSlave
(
input clk_i,
input rst_n_i
);
parameter g_addr_width = 32;
parameter g_data_width = 32;
typedef virtual IWishboneSlave VIWishboneSlave;
IWishboneSlave #(g_addr_width, g_data_width) TheSlave (clk_i, rst_n_i);
t_wishbone_slave_in in;
t_wishbone_slave_out out;
modport slave
(
input in,
output out
);
assign TheSlave.cyc = in.cyc;
assign TheSlave.stb = in.stb;
assign TheSlave.we = in.we;
assign TheSlave.sel = in.sel;
assign TheSlave.adr = in.adr;
assign TheSlave.dat_i = in.dat;
assign out.ack = TheSlave.ack;
assign out.stall = TheSlave.stall;
assign out.rty = TheSlave.rty;
assign out.err = TheSlave.err;
assign out.dat = TheSlave.dat_o;
function automatic CWishboneAccessor get_accessor();
return TheSlave.get_accessor();
endfunction // get_accessor
initial begin
@(posedge rst_n_i);
@(posedge clk_i);
TheSlave.settings.mode = PIPELINED;
TheSlave.settings.stall_prob = 0.1;
TheSlave.settings.gen_random_stalls = 1;
TheSlave.settings.stall_min_duration = 1;
TheSlave.settings.stall_max_duration = 5;
end
endinterface // IVHDWishboneSlave
sim_tool = "modelsim"
top_module="main"
syn_device="xc6slx45t"
sim_top="main"
action = "simulation"
target = "xilinx"
fetchto = "../../ip_cores"
include_dirs=[ "../../sim", "../include", "../../ip_cores/gn4124-core/hdl/gn4124core/sim/gn4124_bfm" ]
include_dirs=[ "../../sim", "../include" ]
vcom_opt = "-mixedsvvh l"
files = [ "main.sv" ]
modules = { "local" : [ "../../top/spec", "../../ip_cores/gn4124-core/hdl/gn4124core/sim/gn4124_bfm" ] }
ctrls = ["bank3_32b_32b"]
\ No newline at end of file
This diff is collapsed.
This diff is collapsed.
......@@ -9,10 +9,8 @@ modules = {
"../../ip_cores/gn4124-core",
"../../ip_cores/general-cores",
"../../ip_cores/wr-cores",
"../../ip_cores/wr-cores/board/spec"
],
"git" : [
"git://ohwr.org/hdl-core-lib/etherbone-core.git",
],
"../../ip_cores/wr-cores/board/spec",
"../../ip_cores/ddr3-sp6-core"
]
}
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