Commit c2a10e64 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

hdl: independent FIFO buffers per channel - top level verified on the SVEC

parent 8b800231
......@@ -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;
--=================================================================================================
-- architecture begin
......@@ -149,9 +149,9 @@ begin
begin
if rising_edge (clk_i) then
if rst_i = '1' then
timestamp_valid_o <= '0';
timestamp_valid_int <= '0';
else
timestamp_valid_o <= acam_tstamp1_ok_p_i or acam_tstamp2_ok_p_i;
timestamp_valid_int <= acam_tstamp1_ok_p_i or acam_tstamp2_ok_p_i;
end if;
end if;
end process;
......@@ -333,8 +333,15 @@ begin
full_timestamp(63 downto 32) <= coarse_time;
full_timestamp(95 downto 64) <= utc;
full_timestamp(127 downto 96) <= metadata;
timestamp_o <= full_timestamp;
process(clk_i)
begin
if rising_edge(clk_i) then
timestamp_o <= full_timestamp;
timestamp_valid_o <= timestamp_valid_int;
end if;
end process;
end rtl;
----------------------------------------------------------------------------------------------------
......
......@@ -549,7 +549,7 @@ clk_period <= f_pick(g_simulation, c_SIM_CLK_PERIOD, c_SYN_CLK_PERIOD);
---------------------------------------------------------------------------------------------------
start_dis_o <= '0';
channel_enable_o <= acam_inputs_en(4 downto 0);
channel_enable_o <= acam_inputs_en(20 downto 16);
end rtl;
----------------------------------------------------------------------------------------------------
......
......@@ -416,9 +416,6 @@ begin
end generate gen_fifos;
irq_tstamp <= '1' when unsigned(irq_channel) /= 0 else '0';
p_gen_1ms_tick : process(clk_tdc_i)
begin
if rising_edge(clk_tdc_i) then
......@@ -515,21 +512,23 @@ begin
-- 2 -> ACAM error
cmp_tdc_eic : tdc_eic
port map
(clk_sys_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
wb_adr_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).dat,
wb_dat_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).dat,
wb_cyc_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).cyc,
wb_sel_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).sel,
wb_stb_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).stb,
wb_we_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).we,
wb_ack_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).ack,
wb_stall_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).stall,
wb_int_o => wb_irq_o,
irq_tdc_tstamps_i => irq_tstamp,
irq_tdc_time_i => '0',
irq_tdc_acam_err_i => '0');
(clk_sys_i => clk_sys_i,
rst_n_i => rst_sys_n_i,
wb_adr_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).adr(3 downto 2),
wb_dat_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).dat,
wb_dat_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).dat,
wb_cyc_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).cyc,
wb_sel_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).sel,
wb_stb_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).stb,
wb_we_i => cnx_master_out(c_WB_SLAVE_TDC_EIC).we,
wb_ack_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).ack,
wb_stall_o => cnx_master_in(c_WB_SLAVE_TDC_EIC).stall,
wb_int_o => wb_irq_o,
irq_tdc_fifo1_i => irq_channel(0),
irq_tdc_fifo2_i => irq_channel(1),
irq_tdc_fifo3_i => irq_channel(2),
irq_tdc_fifo4_i => irq_channel(3),
irq_tdc_fifo5_i => irq_channel(4));
-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-- Unused wishbone signals
......
......@@ -726,24 +726,25 @@ package tdc_core_pkg is
---------------------------------------------------------------------------------------------------
component tdc_eic
port
(rst_n_i : in std_logic;
clk_sys_i : in std_logic;
wb_adr_i : in std_logic_vector(1 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;
wb_int_o : out std_logic;
irq_tdc_tstamps_i : in std_logic;
irq_tdc_time_i : in std_logic;
irq_tdc_acam_err_i : in std_logic);
component 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_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;
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);
end component tdc_eic;
......
This diff is collapsed.
......@@ -85,8 +85,17 @@ architecture rtl of timestamp_fifo is
signal channel_id : std_logic_vector(2 downto 0);
signal ts_match : std_logic;
signal seq_counter : unsigned(31 downto 0);
signal timestamp_with_seq : std_logic_vector(127 downto 0);
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
port map (
rst_n_i => rst_n_sys_i,
......@@ -114,6 +123,7 @@ begin
if rst_tdc_i = '1' 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
......@@ -123,24 +133,43 @@ begin
end if;
end process;
regs_in.fifo_ts0_i <= timestamp_with_seq(31 downto 0);
regs_in.fifo_ts1_i <= timestamp_with_seq(63 downto 32);
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)
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.ltsctl_valid_i <= '0';
regs_in.csr_last_valid_i <= '0';
else
if (enable_i = '1' and ts_match = '1') then
regs_in.ltsctl_valid_i <= '1';
last_ts <= timestamp_i;
elsif (regs_out.ltsctl_valid_o = '0' and regs_out.ltsctl_valid_load_o = '1') then
regs_in.ltsctl_valid_i <= '0';
-- 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.ltsctl_valid_o = '0' and regs_out.ltsctl_valid_load_o = '1') then
regs_in.lts0_i <= last_ts(127 downto 96);
regs_in.lts1_i <= last_ts(95 downto 64);
regs_in.lts2_i <= last_ts(63 downto 32);
regs_in.lts3_i <= last_ts(31 downto 0);
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);
end if;
end if;
end if;
......@@ -152,7 +181,7 @@ begin
if rst_tdc_i = '1' or enable_i = '0' then
buf_irq_int <= '0';
else
if(buf_count = 0) then
if(regs_out.fifo_wr_empty_o = '1') then
buf_irq_int <= '0';
tmr_timeout <= (others => '0');
else
......@@ -172,7 +201,7 @@ begin
-- Case 2: amount of data exceeded the threshold - assert the IRQ
-- line immediately.
if(buf_count > unsigned(irq_threshold_i(9 downto 0))) then
if(regs_out.fifo_wr_full_o = '1' or (buf_count > unsigned(irq_threshold_i(9 downto 0)))) then
buf_irq_int <= '1';
end if;
end if;
......
This diff is collapsed.
......@@ -2,11 +2,11 @@
-- Title : Wishbone slave core for Timestamp FIFO
---------------------------------------------------------------------------------------
-- File : timestamp_fifo_wbgen2_pkg.vhd
-- Author : auto-generated by wbgen2 from timestamp_fifo_wb.wb
-- Created : Tue Apr 14 16:47:08 2015
-- Author : auto-generated by wbgen2 from wbgen/timestamp_fifo_wb.wb
-- Created : Mon Apr 20 17:34:12 2015
-- Standard : VHDL'87
---------------------------------------------------------------------------------------
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE timestamp_fifo_wb.wb
-- THIS FILE WAS GENERATED BY wbgen2 FROM SOURCE FILE wbgen/timestamp_fifo_wb.wb
-- DO NOT HAND-EDIT UNLESS IT'S ABSOLUTELY NECESSARY!
---------------------------------------------------------------------------------------
......@@ -22,22 +22,28 @@ package tsf_wbgen2_pkg is
type t_tsf_in_registers is record
fifo_wr_req_i : std_logic;
fifo_value_i : std_logic_vector(127 downto 0);
fifo_ts0_i : std_logic_vector(31 downto 0);
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);
ltsctl_valid_i : std_logic;
csr_last_valid_i : std_logic;
end record;
constant c_tsf_in_registers_init_value: t_tsf_in_registers := (
fifo_wr_req_i => '0',
fifo_value_i => (others => '0'),
fifo_ts0_i => (others => '0'),
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'),
ltsctl_valid_i => '0'
csr_last_valid_i => '0'
);
-- Output registers (WB slave -> user design)
......@@ -46,16 +52,18 @@ package tsf_wbgen2_pkg is
fifo_wr_full_o : std_logic;
fifo_wr_empty_o : std_logic;
fifo_wr_usedw_o : std_logic_vector(9 downto 0);
ltsctl_valid_o : std_logic;
ltsctl_valid_load_o : std_logic;
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'),
ltsctl_valid_o => '0',
ltsctl_valid_load_o => '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;
......@@ -87,12 +95,15 @@ function "or" (left, right: t_tsf_in_registers) return t_tsf_in_registers is
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_value_i := f_x_to_zero(left.fifo_value_i) or f_x_to_zero(right.fifo_value_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.ltsctl_valid_i := f_x_to_zero(left.ltsctl_valid_i) or f_x_to_zero(right.ltsctl_valid_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;
end function;
end package body;
......@@ -5,25 +5,41 @@ peripheral {
prefix = "tdc_eic";
irq {
name = "FMC TDC timestamps interrupt (FIFO1)";
description = "FMC TDC FIFO1 not empty.";
prefix = "tdc_fifo1";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC timestamps interrupt (FIFO2)";
description = "FMC TDC FIFO1 not empty.";
prefix = "tdc_fifo2";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC timestamps interrupt";
description = "FMC TDC timestamp interrupt (rising edge sensitive).";
prefix = "tdc_tstamps";
trigger = EDGE_RISING;
name = "FMC TDC timestamps interrupt (FIFO3)";
description = "FMC TDC FIFO3 not empty.";
prefix = "tdc_fifo3";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC time interrupt";
description = "FMC TDC time interrupt (rising edge sensitive).";
prefix = "tdc_time";
trigger = EDGE_RISING;
name = "FMC TDC timestamps interrupt (FIFO4)";
description = "FMC TDC FIFO4 not empty.";
prefix = "tdc_fifo4";
trigger = LEVEL_1;
};
irq {
name = "FMC TDC acam error interrupt";
description = "FMC slot 1 acam error interrupt (rising edge sensitive).";
prefix = "tdc_acam_err";
trigger = EDGE_RISING;
name = "FMC TDC timestamps interrupt (FIFO5)";
description = "FMC TDC FIFO5 not empty.";
prefix = "tdc_fifo5";
trigger = LEVEL_1;
};
};
......@@ -15,14 +15,35 @@ peripheral {
name = "Timestamp FIFO";
clock = "clk_tdc_i";
flags_bus = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
flags_bus = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT, FIFO_CLEAR};
flags_dev = {FIFO_FULL, FIFO_EMPTY, FIFO_COUNT};
field {
name = "The timestamp";
prefix = "value";
name = "The timestamp (word 0)";
prefix = "ts0";
type = SLV;
size = 128;
size = 32;
};
field {
name = "The timestamp (word 1)";
prefix = "ts1";
type = SLV;
size = 32;
};
field {
name = "The timestamp (word 2)";
prefix = "ts2";
type = SLV;
size = 32;
};
field {
name = "The timestamp (word 4)";
prefix = "ts3";
type = SLV;
size = 32;
};
};
......@@ -84,19 +105,31 @@ peripheral {
};
};
reg {
name = "Last Timestamp Control/Status";
prefix = "LTSCTL";
name = "Control/Status";
prefix = "CSR";
field {
name = "Last Timestamp Valid";
clock = "clk_tdc_i";
prefix = "VALID";
prefix = "LAST_VALID";
type = BIT;
access_bus = READ_WRITE;
access_dev = READ_WRITE;
load = LOAD_EXT;
};
field {
name = "Reset Sequence Counter";
clock = "clk_tdc_i";
prefix = "RST_SEQ";
type = MONOSTABLE;
};
};
};
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -51,12 +51,12 @@ module fake_acam(
if (addr == 8) begin
acam_fifo_entry ent;
ent=fifo1.pop_front();
data <= ent.ts | (ent.channel << 26);
data <= ent.ts | (ent.channel << 26) | (1<<17);
end else if (addr == 9) begin
acam_fifo_entry ent;
ent=fifo2.pop_front();
data <= ent.ts | (ent.channel << 26);
data <= ent.ts | (ent.channel << 26) | (1<<17);
end else
data <= 28'bz;
......@@ -218,7 +218,7 @@ module main;
acc.write('hc13004, 'hf); // enable EIC irq
acc.write('hc12084, 'h1f); // enable all ACAM inputs
acc.write('hc12084, 'h1f0000); // enable all ACAM inputs
acc.write('hc120fc, (1<<0)); // start acquisition
acc.write('hc120fc, (1<<0)); // start acquisition
......@@ -230,11 +230,11 @@ module main;
#300us;
fork
forever begin
acc.read('hc15000 + `ADDR_TSF_LTSCTL, d);
acc.read('hc15000 + `ADDR_TSF_CSR, d);
if(d&1) begin
uint64_t t0,t1,t2,t3;
acc.write('hc15000 + `ADDR_TSF_LTSCTL, 0);
acc.write('hc15000 + `ADDR_TSF_CSR, 0);
acc.read('hc15000 + `ADDR_TSF_LTS0, t0);
acc.read('hc15000 + `ADDR_TSF_LTS1, t1);
acc.read('hc15000 + `ADDR_TSF_LTS2, t2);
......@@ -244,8 +244,23 @@ module main;
end
acc.read('hc15000 + `ADDR_TSF_FIFO_CSR, d);
// $display("FIFO CSR %x", d);
/* -----\/----- EXCLUDED -----\/-----
if(!(d&`TSF_FIFO_CSR_EMPTY)) begin
uint64_t t0,t1,t2,t3;
acc.read('hc15000 + `ADDR_TSF_FIFO_R0, t0);
acc.read('hc15000 + `ADDR_TSF_FIFO_R1, t1);
acc.read('hc15000 + `ADDR_TSF_FIFO_R2, t2);
acc.read('hc15000 + `ADDR_TSF_FIFO_R3, t3);
$display("Fifo: %08x %08x %08x %08x",t0,t1,t2,t3);
end
-----/\----- EXCLUDED -----/\----- */
end
......
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