---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 05/12/2009 -- Design Name: -- Module Name: timestamp_timing_analyzer - Behavioral -- Project Name: -- Target Devices: -- Tool versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL; ---- Uncomment the following library declaration if instantiating ---- any Xilinx primitives in this code. library UNISIM; use UNISIM.VComponents.all; entity timestamp_timing_analyzer_sigdis is Port ( clk : in STD_LOGIC; reset : in STD_LOGIC; -- normal sync reset design reset activate : in STD_LOGIC; -- keep active high whenever you want to be sensitive for triggers done : out STD_LOGIC; clear : in STD_LOGIC; -- clears the done; next activate will start recording signals : in STD_LOGIC_VECTOR(1 downto 0); trigger_mask: in STD_LOGIC_VECTOR(1 downto 0); timestamp: in STD_LOGIC_VECTOR(13 downto 0); clk_scsn : in STD_LOGIC; readout_value : out STD_LOGIC_VECTOR (31 downto 0); readout_address : in STD_LOGIC_VECTOR (8 downto 0) ); end timestamp_timing_analyzer_sigdis; architecture Behavioral of timestamp_timing_analyzer_sigdis is signal transition, trans_reg, trans_reg2, trans_reg3, sig_reg, sig_reg2, sig_reg3, sig_reg2_clr, sig_reg_clr: std_logic_vector(15 downto 0); signal reset_count_enable, count_enable: std_logic; signal mem_we, mem_we2 : std_logic; signal trans_or: std_logic ; signal counter: std_logic_vector(8 downto 0); signal clear_signal: std_logic; signal done_signal: std_logic; type type_signals_reg is array (0 to 6) of std_logic_vector(1 downto 0); signal signals_reg : type_signals_reg; signal comp, comp1, comp2, comp3 : std_logic_vector(15 downto 0); signal comp4 : std_logic; -- signal trigger_mask_reg: std_logic_vector(15 downto 0); signal trigger_trap_reset: std_logic_vector(15 downto 0); begin clear_signal <= clear or reset; -- trigger logic: start if one of the trigger signals changes -- detect signal change trigger_chain: for i in 0 to 1 generate process(reset, clk, signals(i)) begin if reset = '1' then sig_reg(i) <= '0'; elsif (clk'event and clk='1') then sig_reg(i) <= signals(i); end if; end process; process(reset, clk, sig_reg_clr(i)) begin if reset = '1' then sig_reg2(i) <= '0'; elsif (clk'event and clk='1') then sig_reg2(i) <= sig_reg_clr(i); end if; end process; process(reset, clk, sig_reg2_clr(i)) begin if reset = '1' then sig_reg3(i) <= '0'; elsif (clk'event and clk='1') then sig_reg3(i) <= sig_reg2_clr(i); end if; end process; process(sig_reg(i), sig_reg2(i), trigger_mask(i)) begin if sig_reg(i) = '1' and sig_reg2(i) = '0' and trigger_mask(i) = '1' then transition(i) <= '1'; else transition(i) <= '0'; end if; end process; -- don't use trigger mask here only -- one logic in a clk160 frame and trigger_mask(i)); -- after a clear prevent the trigger from being started by an old change -- set all registers to the signal value if there is a reset sig_reg2_clr(i) <= sig_reg2(i) when clear_signal = '0' else signals(i); sig_reg_clr(i) <= sig_reg(i) when clear_signal = '0' else signals(i); end generate; -- idea use larger buffer and use clk40 in the trigger decision logic !!!!!!!! -- trigger comperator don't use --sig2 <= '1' when transition /= X"00000000" else '0'; -- due to timing problems in the clk160 domain -- use pipeline structure for the comparison because of timing issues -- in each pipelinestep one LUT (4 inputs 1 output) -- this costs a view presamples trigger_register: for ii in 0 to 1 generate process(clk, reset, transition(ii)) begin if reset = '1' then trans_reg(ii) <= '0';--X"0000"; elsif clk'event and clk = '1' then trans_reg(ii) <= transition(ii); end if; end process; end generate; trigger_mask_reg: for ii in 0 to 1 generate trigger_trap_reset(ii) <= reset or (not activate) or clear_signal or (not trigger_mask(ii)) or done_signal; process(clk, trigger_trap_reset(ii),reset, trans_reg(ii), trans_reg2(ii)) begin if trigger_trap_reset(ii) = '1' then trans_reg2(ii) <= '0'; elsif clk'event and clk = '1' then trans_reg2(ii) <= trans_reg(ii); -- or trans_reg2(ii); end if; end process; process(clk, reset, trans_reg2(ii)) begin if reset = '1' then trans_reg3(ii) <= '0'; elsif clk'event and clk = '1' then trans_reg3(ii) <= trans_reg2(ii); end IF; end process; end generate; -- make the or of all possible triggers as pipeline -- first pipeline step: update this is not possible due to hardware limitations delay the trigger signal instead. -- select only between two trigger lines. (one physical trigger one fast trigger) --process(clk,trans_reg3(2 downto 3), reset) --DEBUG --begin -- if reset = '1' then -- comp1(0) <= '0'; -- elsif clk'event and clk = '1' then -- comp1(0) <= trans_reg3(2) or trans_reg3(0); -- end if; --end process; --sig2 <= trans_reg3(0); --trans_reg(0); process(clk,reset) begin if reset ='1' then trans_or <= '0'; elsif clk'event and clk = '1' then if trans_reg(0) = '1' or trans_reg(1) ='1' then trans_or <= '1'; else trans_or <= '0'; end if; end if; end process; --trigger trap important to have a contiouus clk_en for the memory counter --sig8 <= sig2;-- and activate; activation is done in the reset signal --sig3 <= sig8 or count_enable; process(clk,trans_reg2(0),reset_count_enable, count_enable) begin if reset_count_enable ='1' then count_enable <= '0'; elsif clk'event and clk = '1' then count_enable <= trans_or; -- or count_enable; end if; end process; reset_count_enable <= done_signal or clear_signal or reset; --count_enable <= sig2; --count_enable <= trans_reg2(0); -- memory address counter process(clk,reset) begin if reset ='1' then mem_we <= '0'; elsif clk'event and clk = '1' then mem_we <= count_enable; end if; end process; process(clk,reset) begin if reset ='1' then mem_we2 <= '0'; elsif clk'event and clk = '1' then mem_we2 <= mem_we; end if; end process; process(clk, reset, counter, clear_signal, count_enable) begin if clear_signal = '1' then counter <= "000000000"; elsif clk'event and clk='1' and count_enable = '1' then counter <= counter + '1'; end if; end process; -- stop recording if memory is full done_signal <= '1' when ((counter = 510) or (counter = 511)) else '0'; -- buffer for presamples --signals_reg(0) <= sig_reg3(15 downto 0); signals_reg(0) <= signals; -- DEBUG presamples: for jj in 1 to 6 generate process(reset, clk, signals_reg(jj-1)) begin if reset = '1' then signals_reg(jj) <= (others => '0'); elsif clk'event and clk='1' then signals_reg(jj) <= signals_reg(jj-1); end if; end process; end generate; -- memory to store counter value and trigger pattern RAMB16_S36_S36_inst : RAMB16_S36_S36 generic map ( INIT_A => X"000000000", -- Value of output RAM registers on Port A at startup INIT_B => X"000000000", -- Value of output RAM registers on Port B at startup SRVAL_A => X"000000000", -- Port A ouput value upon SSR assertion SRVAL_B => X"000000000", -- Port B ouput value upon SSR assertion WRITE_MODE_A => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE WRITE_MODE_B => "WRITE_FIRST", -- WRITE_FIRST, READ_FIRST or NO_CHANGE --SIM_COLLISION_CHECK => "NONE", -- "NONE", "WARNING", "GENERATE_X_ONLY", "ALL" -- The following INIT_xx declarations specify the initial contents of the RAM -- Address 0 to 127 INIT_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 128 to 255 INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 256 to 383 INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 384 to 511 INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000", INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000", -- The next set of INITP_xx are for the parity bits -- Address 0 to 127 INITP_00 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 128 to 255 INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 256 to 383 INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000", -- Address 384 to 511 INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000", INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000") port map ( DOA => open, -- Port A 32-bit Data Output DOB => readout_value, -- Port B 32-bit Data Output DOPA => open, -- Port A 4-bit Parity Output DOPB => open, -- Port B 4-bit Parity Output ADDRA => counter, -- Port A 9-bit Address Input ADDRB => readout_address, -- Port B 9-bit Address Input CLKA => clk, -- Port A Clock CLKB => clk_scsn, -- Port B Clock DIA(1 downto 0) => signals_reg(6), --DEBUG signals_reg(4),--sig_reg3(31 downto 0), -- Port A 32-bit Data Input DIA(15 downto 2) => timestamp, --DEBUG signals_reg(4),--sig_reg3(31 downto 0), -- Port A 32-bit Data Input DIA(31 downto 16) => X"0000", DIB => X"01011000", -- Port B 32-bit Data Input DIPA => X"0", -- Port A 4-bit parity Input DIPB => X"0", -- Port-B 4-bit parity Input ENA => '1', -- Port A RAM Enable Input ENB => '1', -- PortB RAM Enable Input SSRA => reset, -- Port A Synchronous Set/Reset Input SSRB => reset, -- Port B Synchronous Set/Reset Input WEA => mem_we2, -- Port A Write Enable Input WEB => '0' -- Port B Write Enable Input ); done <= done_signal; end Behavioral;