diff --git a/scripts/filesets/ttc_emulator_fileset.tcl b/scripts/filesets/ttc_emulator_fileset.tcl index 4ce132cd5f39940dc4ed62045b4abec38dfcee58..9fe1e8b91ed96626e6e18aeb2e6b29d26f08d5c5 100644 --- a/scripts/filesets/ttc_emulator_fileset.tcl +++ b/scripts/filesets/ttc_emulator_fileset.tcl @@ -2,6 +2,7 @@ set VHDL_FILES [concat $VHDL_FILES \ TTCdataEmulator/TTC_Emulator.vhd \ TTCdataEmulator/delay_chain.vhd \ + TTCdataEmulator/signal_delay.vhd \ TTCdataEmulator/hilo_detect.vhd \ TTCdataEmulator/pulse_extender.vhd \ packages/FELIX_package.vhd] diff --git a/sources/TTCdataEmulator/TTC_Emulator.vhd b/sources/TTCdataEmulator/TTC_Emulator.vhd index 3080ba5b1822944dcab8a90e13f1b97a4f620ec3..9cbd7031c54b1185b7d01f6fb24d219e390a92a2 100644 --- a/sources/TTCdataEmulator/TTC_Emulator.vhd +++ b/sources/TTCdataEmulator/TTC_Emulator.vhd @@ -1,8 +1,13 @@ -------------------------------------------------------------------------------- --- Design : ttc_emulator_v2 +-- Design : ttc_emulator_v2.1 -- Author : Alessandra Camplani -- Email : alessandra.camplani@cern.ch -- Created : 22.01.2020 +-- Revised by : Ali Skaf +-- Email : ali.skaf@uni-goettingen.de +-- V2.1: provide OCR and long Bchannel support +-- Last edited; 21.10.2021 + -------------------------------------------------------------------------------- -------------------------------------------------------------------------------- @@ -45,7 +50,7 @@ architecture Behavioral of TTC_Emulator is signal input_bcr_period_r : unsigned(31 downto 0); signal input_long_Bch : std_logic_vector(31 downto 0); -- default ... - signal input_broadcast : std_logic_vector(5 downto 0); -- default ... + signal input_broadcast : std_logic_vector(5 downto 0); signal set_default : std_logic; signal cycle_mode : std_logic; @@ -56,6 +61,8 @@ architecture Behavioral of TTC_Emulator is signal single_bcr_long : std_logic := '0'; signal single_bcr : std_logic := '0'; + signal ocr : std_logic := '0'; -- AS: OCR command signal: Single pulse generated at rising edge of BROADCAST(0) + signal en : std_logic := '0'; signal user_reset : std_logic := '0'; @@ -85,8 +92,6 @@ architecture Behavioral of TTC_Emulator is signal Bch_l1_fifo_wr : std_logic; signal short_info : std_logic_vector(5 downto 0); signal short_hamming : std_logic_vector(4 downto 0); - signal long_info_0 : std_logic_vector(14 downto 0); - signal long_info_1 : std_logic_vector(15 downto 0); signal long_hamming : std_logic_vector(6 downto 0); signal fifo_wr : std_logic; @@ -101,16 +106,16 @@ architecture Behavioral of TTC_Emulator is signal short_b_bchan_valid : std_logic; signal fifo_bchan_valid : std_logic; - signal Bch_short_cnt_init : unsigned(4 downto 0) := "10000"; - signal fifo_cnt_init : unsigned(6 downto 0) := "1000000"; + constant Bch_short_cnt_init : unsigned(4 downto 0) := "10000"; + constant fifo_cnt_init : unsigned(6 downto 0) := "1000000"; - signal short_bch_cnt : unsigned(4 downto 0) := "10000"; - signal fifo_bch_cnt : unsigned(6 downto 0) := "1000000"; + signal short_bch_cnt : unsigned(4 downto 0) := Bch_short_cnt_init; --AS: "10000"; + signal fifo_bch_cnt : unsigned(6 downto 0) := fifo_cnt_init ; --AS: "1000000"; signal serialization_process : std_logic := '0'; signal Serial_Bchannel : std_logic := '1'; signal Serial_Bchannel_r : std_logic := '1'; - type state_type is (idle, init, shortB, longB); + type state_type is (idle, shortB, longB);--(idle, init, shortB, longB); signal state : state_type; signal sm_short_cnt : unsigned(3 downto 0); signal sm_long_cnt : unsigned(6 downto 0); @@ -159,8 +164,8 @@ begin input_ecr_period <= unsigned(register_map_control.TTC_EMU_ECR_PERIOD); input_bcr_period <= unsigned(register_map_control.TTC_EMU_BCR_PERIOD); - input_long_Bch <= (register_map_control.TTC_EMU_LONG_CHANNEL_DATA); - input_broadcast <= (register_map_control.TTC_EMU_CONTROL.BROADCAST); + input_long_Bch <= (register_map_control.TTC_EMU_LONG_CHANNEL_DATA); --AS: used for individually addressed command + input_broadcast <= (register_map_control.TTC_EMU_CONTROL.BROADCAST); --AS: set delay bits(4:1) and OCR = bit(0) set_default <= to_sl(register_map_control.TTC_EMU_RESET); @@ -227,6 +232,17 @@ begin sig_out => single_bcr -- output signal ); + ocr_detect: entity work.hilo_detect + generic map ( + lohi => true + ) + port map ( + clk => Clock, -- clock + sig_in => input_broadcast(0), -- input signal + sig_out => ocr -- output signal + ); + + reset_detect: entity work.hilo_detect generic map ( lohi => true @@ -401,25 +417,56 @@ begin -- D= Data, 8 bits -- H= Hamming Code, 7 bits -- +-- AS: input_long_Bch= AAAAAAAAAAAAAAE1SSSSSSSSDDDDDDDD +-- We need to calculate corresponding Hamming code for input_long_Bch = d[31..0] +-- +-- h[0] = d[0]^d[1]^d[2]^d[3]^d[4]^d[5]; +-- h[1] = d[6]^d[7]^d[8]^d[9]^d[10]^d[11]^d[12]^d[13]^d[14]^d[15]^d[16]^d[17]^d[18]^d[19]^d[20]; +-- h[2] = d[6]^d[7]^d[8]^d[9]^d[10]^d[11]^d[12]^d[13]^d[21]^d[22]^d[23]^d[24]^d[25]^d[26]^d[27]; +-- h[3] = d[0]^d[1]^d[2]^d[6]^d[7]^d[8]^d[9]^d[14]^d[15]^d[16]^d[17]^d[21]^d[22]^d[23]^d[24]^d[28]^d[29]^d[30]; +-- h[4] = d[0]^d[3]^d[4]^d[6]^d[7]^d[10]^d[11]^d[14]^d[15]^d[18]^d[19]^d[21]^d[22]^d[25]^d[26]^d[28]^d[29]^d[31]; +-- h[5] = d[1]^d[3]^d[5]^d[6]^d[8]^d[10]^d[12]^d[14]^d[16]^d[18]^d[20]^d[21]^d[23]^d[25]^d[27]^d[28]^d[30]^d[31]; +-- h[6] = hmg[0]^hmg[1]^hmg[2]^hmg[3]^hmg[4]^hmg[5]^d[0]^d[1]^d[2]^d[3]^d[4]^d[5]^d[6]^d[7]^d[8]^d[9]^d[10]^d[11]^d[12]^d[13]^d[14]^d[15]^d[16]^d[17]^d[18]^d[19]^d[20]^d[21]^d[22]^d[23]^d[24]^d[25]^d[26]^d[27]^d[28]^d[29]^d[30]^d[31]; + + long_hamming(0) <= input_long_Bch(0) xor input_long_Bch(1) xor input_long_Bch(2) xor input_long_Bch(3) xor input_long_Bch(4) xor input_long_Bch(5); + + long_hamming(1) <= input_long_Bch(6) xor input_long_Bch(7) xor input_long_Bch(8) xor input_long_Bch(9) xor input_long_Bch(10) xor input_long_Bch(11) xor + input_long_Bch(12) xor input_long_Bch(13) xor input_long_Bch(14) xor input_long_Bch(15) xor input_long_Bch(16) xor + input_long_Bch(17) xor input_long_Bch(18) xor input_long_Bch(19) xor input_long_Bch(20); - -- For the moment all at zero - long_info_0 <= x"000" & "00" & '1'; -- A (14) + E (1) - long_info_1 <= x"00" & "11010011"; -- S (8) + D (8) - long_hamming <= (others => '0'); -- H (7) + long_hamming(2) <= input_long_Bch(6) xor input_long_Bch(7) xor input_long_Bch(8) xor input_long_Bch(9) xor input_long_Bch(10) xor input_long_Bch(11) xor + input_long_Bch(12) xor input_long_Bch(13) xor input_long_Bch(21) xor input_long_Bch(22) xor input_long_Bch(23) xor + input_long_Bch(24) xor input_long_Bch(25) xor input_long_Bch(26) xor input_long_Bch(27); + long_hamming(3) <= input_long_Bch(0) xor input_long_Bch(1) xor input_long_Bch(2) xor input_long_Bch(6) xor input_long_Bch(7) xor input_long_Bch(8) xor input_long_Bch(9) xor + input_long_Bch(11) xor input_long_Bch(14) xor input_long_Bch(15) xor input_long_Bch(16) xor input_long_Bch(17) xor input_long_Bch(21) xor + input_long_Bch(22) xor input_long_Bch(23) xor input_long_Bch(24) xor input_long_Bch(28) xor input_long_Bch(29) xor input_long_Bch(30); + + long_hamming(4) <= input_long_Bch(0) xor input_long_Bch(3) xor input_long_Bch(4) xor input_long_Bch(6) xor input_long_Bch(7) xor input_long_Bch(10) xor + input_long_Bch(11) xor input_long_Bch(14) xor input_long_Bch(15) xor input_long_Bch(18) xor input_long_Bch(19) xor input_long_Bch(21) xor + input_long_Bch(22) xor input_long_Bch(25) xor input_long_Bch(26) xor input_long_Bch(28) xor input_long_Bch(29) xor input_long_Bch(31); + + long_hamming(5) <= input_long_Bch(1) xor input_long_Bch(3) xor input_long_Bch(5) xor input_long_Bch(6) xor input_long_Bch(8) xor input_long_Bch(10) xor + input_long_Bch(12) xor input_long_Bch(14) xor input_long_Bch(16) xor input_long_Bch(18) xor input_long_Bch(20) xor input_long_Bch(21) xor + input_long_Bch(23) xor input_long_Bch(25) xor input_long_Bch(27) xor input_long_Bch(28) xor input_long_Bch(30) xor input_long_Bch(31); + + long_hamming(6) <= input_long_Bch(2) xor input_long_Bch(4) xor input_long_Bch(5) xor input_long_Bch(7) xor input_long_Bch(8) xor input_long_Bch(10) xor + input_long_Bch(11) xor input_long_Bch(13) xor input_long_Bch(14) xor input_long_Bch(17) xor input_long_Bch(19) xor input_long_Bch(20) xor + input_long_Bch(21) xor input_long_Bch(24) xor input_long_Bch(26) xor input_long_Bch(27) xor input_long_Bch(29) xor input_long_Bch(30) xor input_long_Bch(31); + process(Clock) begin if rising_edge(Clock) then if Reset = '1' or user_reset = '1' then elsif l1_accept = '1' then - Bch_long <= '0' & '1' & long_info_0 & '1' & long_info_1 & long_hamming & "1" ; + Bch_long <= '0' & '1' & input_long_Bch & long_hamming & "1" ; Bch_l1_fifo_wr <= '1'; - add_s8_i <= long_info_1(15 downto 8); + add_s8_i <= input_long_Bch(15 downto 8); add_strobe_i <= '1'; - add_e_i <= long_info_0(0); - add_d8_i <= long_info_1(7 downto 0); + add_e_i <= input_long_Bch(16); + add_d8_i <= input_long_Bch(7 downto 0); else Bch_long <= (others => '1'); @@ -603,28 +650,20 @@ begin sig_out => fifo_bchan_valid -- output signal ); +--FS: For 1 clock delay, we simply push our signals through a single flipflop. - short_b_prep_delay: entity work.delay_chain - generic map ( - d_depth => 1 -- number of clock cycles it shell be delayed - ) - port map ( - clk => Clock, -- clock - rst => Reset, -- sync reset - sig_in(0) => prepare_bcr, -- input signal - sig_out(0) => prepare_bcr_r -- delayed output signal - ); - - short_e_prep_delay: entity work.delay_chain - generic map ( - d_depth => 1 -- number of clock cycles it shell be delayed - ) - port map ( - clk => Clock, -- clock - rst => Reset, -- sync reset - sig_in(0) => fifo_read, -- input signal - sig_out(0) => fifo_read_r -- delayed output signal - ); + process(Clock) + begin + if rising_edge(Clock) then + if Reset = '1' then + fifo_read_r <= '0'; + prepare_bcr_r <= '0'; + else + fifo_read_r <= fifo_read; + prepare_bcr_r <= prepare_bcr; + end if; + end if; + end process; -- Depending on what is triggered, with the shortBchannel for the BCR or the fifo output are registered -- The 2 have different lengths @@ -650,16 +689,13 @@ begin begin if rising_edge(Clock) then if Reset = '1' or user_reset = '1'then - Bch_short_cnt_init <= "10000"; - fifo_cnt_init <= "1000000"; + --Bch_short_cnt_init <= "10000"; + --fifo_cnt_init <= "1000000"; short_b <= (others => '1'); short_bch_cnt <= Bch_short_cnt_init-1; fifo_bch_cnt <= fifo_cnt_init-1; else - if cycle_mode = '1' or cycle_mode = '0' then -- this condition can later be removed.. - Bch_short_cnt_init <= "10000"; - fifo_cnt_init <= "1000000"; - + if short_b_bchan_valid = '1' then if short_bch_cnt(short_bch_cnt'left) = '1' then short_bch_cnt <= Bch_short_cnt_init-1; @@ -699,29 +735,26 @@ begin short_bch_cnt <= Bch_short_cnt_init; fifo_bch_cnt <= fifo_cnt_init; end if; - else - Serial_Bchannel <= '1'; - serialization_process <= '0'; - short_b <= (others => '1'); - short_bch_cnt <= Bch_short_cnt_init; - fifo_bch_cnt <= fifo_cnt_init; end if; - end if; - end if; + end if; end process; --------------------------------------------------------------- ----- ECR, BCR decoding --------------------------------------- --------------------------------------------------------------- -- State machine to prerly decoded ECR/BCR from the short Bchannel --- States are (i) IDLE, (ii) INIT and then, depeding on the serialized --- info it can be either (iii) ShortB or (iii) LongB. +-- States are (i) IDLE and then, depeding on the serialized +-- info it can be either (ii) ShortB or (iii) LongB. process(Clock) begin if rising_edge(Clock) then + + Serial_Bchannel_r <= Serial_Bchannel; + if Reset = '1' or user_reset = '1'then sm_short_cnt <= (others => '0'); sm_long_cnt <= (others => '0'); + state <= idle; else Serial_Bchannel_r <= Serial_Bchannel; @@ -729,21 +762,17 @@ begin -- IDLE STATE when idle => - sm_short_cnt <= (others => '0'); - sm_long_cnt <= (others => '0'); - if Serial_Bchannel = '0' and Serial_Bchannel_r = '1' then - state <= init; +-- sm_short_cnt <= (others => '0'); +-- sm_long_cnt <= (others => '0'); + if Serial_Bchannel = '0' and Serial_Bchannel_r = '1' then --AS: falling edge of Serial_Bchannel + state <= ShortB; --init + elsif Serial_Bchannel = '1' and Serial_Bchannel_r = '0' then --AS: rising edge of Serial_Bchannel + state <= longB; else state <= idle; end if; - -- INIT STATE - when init => - if Serial_Bchannel_r = '0' and Serial_Bchannel = '0' then - state <= shortB; - elsif Serial_Bchannel_r = '0' and Serial_Bchannel = '1' then - state <= longB; - end if; + -- INIT STATE -- AS: Removed as no need to have a specific state for this! --SHORT B STATE when shortB => @@ -755,7 +784,7 @@ begin state <= shortB; ecr_dec <= '0'; bcr_dec <= '0'; - + elsif sm_short_cnt = 6 then broad_dec <= broad_dec; broad_done <= '1'; @@ -777,12 +806,12 @@ begin ecr_dec <= '0'; broad_dec <= (others => '0'); broad_done <= '0'; - + else state <= shortB; bcr_dec <= '0'; ecr_dec <= '0'; - broad_dec <= (others => '0'); + broad_dec <= (others => '0'); broad_done <= '0'; end if; @@ -804,29 +833,32 @@ begin -- In the normal decoding, these signals always appear after the Bchannel --- The 15 or 16 clk cycles delay is freely chosen for both (but related to the appearance of the broadcast bits) - bcr_delay: entity work.delay_chain +-- (but related to the appearance of the broadcast bits (4:1)) + bcr_delay: entity work.signal_delay generic map ( - d_depth => 15 -- number of clock cycles it shell be delayed + width => 4 -- number counter stages used to generate delay given in count_in ) port map ( clk => Clock, -- clock - rst => Reset, -- sync reset - sig_in(0) => bcr_dec, -- input signal - sig_out(0) => bcr -- delayed output signal + rst => Reset, -- sync reset* + count_in => unsigned(input_broadcast(4 downto 1)), + sig_in => bcr_dec, -- input signal + sig_out => bcr -- delayed output signal ); - ecr_delay: entity work.delay_chain + ecr_delay: entity work.signal_delay generic map ( - d_depth => 16 -- number of clock cycles it shell be delayed + width => 4 -- number of clock cycles it shell be delayed- number of clock cycles it shell be delayed ) port map ( clk => Clock, -- clock rst => Reset, -- sync reset - sig_in(0) => ecr_dec, -- input signal - sig_out(0) => ecr -- delayed output signal + count_in => unsigned(input_broadcast(4 downto 1)), + sig_in => ecr_dec, -- input signal + sig_out => ecr -- delayed output signal ); + -- Serialization process for both long and short Bchannel process(Clock) begin @@ -861,23 +893,12 @@ begin TTCout(1) <= Serial_Bchannel; TTCout(2) <= bcr or single_bcr; TTCout(3) <= ecr or single_ecr; - TTCout(4) <= broad(5); -- d(0) - TTCout(5) <= broad(4); -- d(1) - TTCout(6) <= broad(3); -- d(2) - TTCout(7) <= broad(2); -- d(3) - TTCout(8) <= broad(1); -- t(0) - TTCout(9) <= broad(0); -- t(1) + TTCout(4) <= ocr; -- AS: use this output instead of broad(0); d(0) + TTCout(5) <= broad(1); -- d(1) + TTCout(6) <= broad(2); -- d(2) + TTCout(7) <= broad(3); -- d(3) + TTCout(8) <= broad(4); -- t(0) + TTCout(9) <= broad(5); -- t(1) - -- To miminc what is in the ttc fmc wrapper - -- TTC_out_unsync(0) <= l1a; - -- TTC_out_unsync(1) <= channelB; - -- TTC_out_unsync(2) <= brc_b; --BCR - -- TTC_out_unsync(3) <= brc_e; --ECR - -- TTC_out_unsync(4) <= brc_d4(0); - -- TTC_out_unsync(5) <= brc_d4(1); - -- TTC_out_unsync(6) <= brc_d4(2); - -- TTC_out_unsync(7) <= brc_d4(3); - -- TTC_out_unsync(8) <= brc_t2(0); - -- TTC_out_unsync(9) <= brc_t2(1); end Behavioral; diff --git a/sources/TTCdataEmulator/signal_delay.vhd b/sources/TTCdataEmulator/signal_delay.vhd new file mode 100644 index 0000000000000000000000000000000000000000..f7ee185e0f0cdfc2b67db8923aa8f81c4900533b --- /dev/null +++ b/sources/TTCdataEmulator/signal_delay.vhd @@ -0,0 +1,62 @@ +--===================================================================================== +-- Company : CERN - University of Goettingen +-- Project : Felix +-- Module : TTC_emulator_v 2.1 +-- Design : signal_delay.vhd +-- Author : Ali Skaf +-- Email : ali.skaf@uni-goettingen.de +-- Created : 6.10.2021 +-- Description : delay an input pulse sig_in for a numner of clks equal to count_in + 1 +--====================================================================================== + +library ieee; +use ieee.std_logic_1164.all; +use IEEE.NUMERIC_STD.ALL; +use IEEE.STD_LOGIC_UNSIGNED.ALL; + +entity signal_delay is +generic ( + width : positive + ); + port ( + clk : in std_logic; + rst : in std_logic; + count_in : in unsigned(width-1 downto 0); + sig_in : in std_logic; + sig_out : out std_logic + ); +end signal_delay; +--======================================================================================== +architecture behavioral of signal_delay is + + signal count_reg : unsigned(width-1 downto 0); + signal enable, sig_r : std_logic; + + begin + process(clk) + begin + if rising_edge(clk) then + if rst = '1' then + count_reg <= (others => '0'); + enable <='0'; + sig_out <= '0'; + else + sig_out <= '0'; + enable <= enable or sig_in; + if enable <= '1' then + count_reg <= count_reg + 1; + if count_reg >= count_in then + enable <='0'; + sig_out <= '1'; + count_reg <= (others => '0'); + end if; + else + sig_out <= '0'; + + end if; + end if; + end if; + end process; + + end behavioral; + --========================================================================================