Commit 5444ee7a authored by David Cussans's avatar David Cussans

Tidied up logic_clocks_rtl.vhd:

* Removed unused code and signals.
* Changed way strobes are generated - use 40MHz clock as input. (Should be much more robust than previous mechanism)
Incremented version number to 23
parent ae0fe926
......@@ -18,7 +18,7 @@
-- "Output Output Phase Duty Pk-to-Pk Phase"
-- "Clock Freq (MHz) (degrees) Cycle (%) Jitter (ps) Error (ps)"
------------------------------------------------------------------------------
-- CLK_OUT1___640.000______0.000______50.0______175.916____213.982
-- CLK_OUT1___320.000______0.000______50.0______175.916____213.982
-- CLK_OUT2___160.000______0.000______50.0______223.480____213.982
-- CLK_OUT3____40.000______0.000______50.0______306.416____213.982
--
......@@ -36,9 +36,9 @@ USE work.ipbus.all;
library unisim;
use unisim.vcomponents.all;
--! @brief Generates 160MHz , 640MHz clocks from an incoming 40MHz clock.
--! Can switch between clock generated from on-board Xtal ( clk_logic_xtal ) and external clock.
--! Can also output clock to external clock pins.
--! @brief Generates 160MHz , 320MHz clocks from an incoming 40MHz clock.
--! Also generates strobes, (one for 160MHz , one for 320MHz clock ) that
--! strobe once for each cycle of 40MHz
--!
--! @author David Cussans , David.Cussans@bristol.ac.uk
--
......@@ -79,45 +79,34 @@ END ENTITY logic_clocks ;
--
ARCHITECTURE rtl OF logic_clocks IS
signal s_clk40 , s_clk40_internal : std_logic;
signal s_clk40 : std_logic;
constant C_NUM_STROBE_TAPS : positive := 3; --! Adjust to shift strobes relative to 40MHz clock edge
signal s_clk40_delayed_160 : std_logic_vector(C_NUM_STROBE_TAPS downto 0); --! Shift register used to generate clock_4x strobe. Adjust length for correct alignment with incoming clock
signal s_clk40_delayed_320 : std_logic_vector(2*C_NUM_STROBE_TAPS downto 0); --! Shift register used to generate clock_8x strobe. Adjust length for correct alignment with incoming clock
signal s_clk160 ,s_clk160_internal : std_logic;
signal ryanclock : std_logic;
signal s_clk320 , s_clk320_internal : std_logic;
signal s_clk40_out : std_logic; -- Clock generated by DDR register to feed out of chip.
--Junk signal s_clk_is_xtal, s_clk_is_ext_buf : std_logic := '0'; -- default to
-- input from ext
-- signal s_logic_clk_rst : std_logic := '0';
signal s_locked_pll, s_locked_bufpll : std_logic;
signal s_locked_pll : std_logic;
signal s_clk : std_logic;
signal s_DUT_Clk, s_DUT_Clk_o, s_DUT_ClkG : std_logic;
signal s_extclk, s_extclkG : std_logic;
-- signal s_clk_d1 , s_strobe_4x_p1 , s_strobe_4x_logic : std_logic;
signal s_clkfbout_buf , s_clkfbout : std_logic;
signal s_strobe_generator : std_logic_vector(3 downto 0) := "1000"; -- ! Store state of ring buffer to generate strobe
signal s_logic_clk_generator : std_logic_vector(3 downto 0) := "1100"; --! Stores state of 40MHz "clock"
--signal s_strobe_generator : std_logic_vector(15 downto 0) := "1111000000000000"; -- ! Store state of ring buffer to generate strobe
--signal s_logic_clk_generator : std_logic_vector(15 downto 0) := "1111111100000000"; --! Stores state of 40MHz "clock"
signal s_strobe160 :std_logic_vector(15 downto 0) := "1000000000000000"; -- 160 strobe ring
signal s_strobe_fb : std_logic := '0';
signal s_DUT_Clk : std_logic;
signal s_clkfbout : std_logic;
signal s_logic_reset_ipb, s_logic_reset_ipb_d1 : std_logic := '0';
-- ! Reset signal in IPBus clock domain
signal s_logic_reset , s_logic_reset_d1 , s_logic_reset_d2 , s_logic_reset_d3 , s_logic_reset_d4 : std_logic := '0';
-- ! reset signal clocked onto logic-clock domain.
signal s_logic_reset_ipb, s_logic_reset_ipb_d1 : std_logic := '0'; --! Reset signal in IPBus clock domain
signal s_logic_reset , s_logic_reset_d1 , s_logic_reset_d2 , s_logic_reset_d3 , s_logic_reset_d4 : std_logic := '0'; --! reset signal clocked onto logic-clock domain.
attribute SHREG_EXTRACT: string;
attribute SHREG_EXTRACT of s_logic_reset_d1: signal is "no"; -- Synchroniser not to be optimised into shre
attribute SHREG_EXTRACT of s_logic_reset_d1: signal is "no"; -- Synchroniser not to be optimised into shreg
attribute SHREG_EXTRACT of s_logic_reset_d2: signal is "no"; -- Synchroniser not to be optimised into shreg
attribute SHREG_EXTRACT of s_logic_reset_d3: signal is "no"; -- Synchroniser not to be optimised into shreg
attribute SHREG_EXTRACT of s_logic_reset_d4: signal is "no"; -- Synchroniser not to be optimised into shreg
attribute SHREG_EXTRACT of s_clk40_delayed_160: signal is "no"; -- delay to help timing not to be optimised into shreg
attribute SHREG_EXTRACT of s_clk40_delayed_320: signal is "no"; -- delay to help timing not to be optimised into shreg
signal s_ipbus_ack : std_logic := '0';
signal s_reset_pll : std_logic := '0';
signal s_reset_pll : std_logic := '0'; -- ! PLL Reset signal
-- ! Global Reset signal
signal s_extclk_internal : std_logic := '0';
signal s_clock_status_ipb : std_logic_vector( ipbus_o.ipb_rdata'range ); --! Hold status of clocks
signal s_clock_status_ipb : std_logic_vector( ipbus_o.ipb_rdata'range ); --! contains status of clocks
BEGIN
-----------------------------------------------------------------------------
......@@ -129,9 +118,6 @@ BEGIN
s_logic_reset_ipb <= '0';
if (ipbus_i.ipb_strobe = '1' and ipbus_i.ipb_write = '1') then
case ipbus_i.ipb_addr(1 downto 0) is
--Junk when "00" =>
--Junk s_clk_is_xtal <= ipbus_i.ipb_wdata(2) ; -- select clock source
when "01" =>
s_logic_reset_ipb <= ipbus_i.ipb_wdata(0) ; -- write to reset
when others => null;
......@@ -142,7 +128,6 @@ BEGIN
s_logic_reset_ipb_d1 <= s_logic_reset_ipb;
s_ipbus_ack <= ipbus_i.ipb_strobe and not s_ipbus_ack;
-- register the clock status signals onto IPBus domain.
--s_clock_status_ipb <= x"0000000" & '0' & s_clk_is_xtal & s_locked_bufpll & s_locked_pll;
s_clock_status_ipb <= x"0000000" & '0' & '0' & '0' & s_locked_pll; -- The only useful bit is now the PLL lock status.
end if;
end process ipbus_write;
......@@ -175,18 +160,10 @@ BEGIN
end process p_reset;
logic_reset_o <= s_logic_reset;
logic_clocks_locked_o <= s_locked_bufpll and s_locked_pll;
logic_clocks_locked_o <= s_locked_pll;
-- Use Generate, since can't figure out how BUFGMUX works
-- gen_extclk_input: if ( g_USE_EXTERNAL_CLK = 1) generate
-- s_DUT_Clk <= s_extclkG; -- Hard wire for now.
-- end generate gen_extclk_input;
-- gen_intclk_input: if ( g_USE_EXTERNAL_CLK = 0) generate
s_DUT_Clk <= clk_logic_xtal_i;
-- end generate gen_intclk_input;
--! Clocking primitive
-------------------------------------
......@@ -194,20 +171,19 @@ BEGIN
pll_base_inst : PLL_BASE
generic map
(BANDWIDTH => "OPTIMIZED",
--CLK_FEEDBACK => "CLKOUT0", --"CLKFBOUT",
CLK_FEEDBACK => "CLKFBOUT",
COMPENSATION => "SYSTEM_SYNCHRONOUS",
DIVCLK_DIVIDE => 1,
CLKFBOUT_MULT => 16,
CLKFBOUT_MULT => 16, -- Run PLL at 640MHz
CLKFBOUT_PHASE => 0.000,
CLKOUT0_DIVIDE => 2, -- 1-->2 move from 640 to 320
CLKOUT0_DIVIDE => 2, -- CLK0 = 320MHz
CLKOUT0_PHASE => 0.000,
CLKOUT0_DUTY_CYCLE => 0.500,
CLKOUT1_DIVIDE => 4, -- 4-->8 move from 160 to 80
CLKOUT1_DIVIDE => 4, -- CLK1 = 160MHz
CLKOUT1_PHASE => 0.000,
CLKOUT1_DUTY_CYCLE => 0.500,
CLKOUT2_DIVIDE => 16, -- 16--> 32 move from 40 to 20
CLKOUT2_PHASE => 0.000,
CLKOUT2_DIVIDE => 16, -- CLK2 = 40MHz
CLKOUT2_PHASE => +16.900, -- Shift 40MHz clock later to avoid negative hold time in strobe generator
CLKOUT2_DUTY_CYCLE => 0.500,
CLKIN_PERIOD => 25.000,
REF_JITTER => 0.010)
......@@ -222,101 +198,36 @@ BEGIN
CLKOUT5 => open,
-- Status and control signals
LOCKED => s_locked_pll,
-- RST => s_logic_clk_rst,
RST => s_reset_pll,
-- Input clock control
-- CLKFBIN => s_clkfbout_buf,
CLKFBIN => s_clkfbout,
CLKIN => s_DUT_clk);
-- CLKIN => clk_logic_xtal_i);
s_reset_pll <= Reset_i or s_logic_reset;
-----------------------------------------------
--BUFPLL not supported by 7 Series. We need to replace it with BUFIO+BUFR
-- Buffer the 16x clock and generate the ISERDES strobe signal
-- BUFPLL_inst : BUFPLL
-- generic map (
-- DIVIDE => 4)
-- port map (
-- IOCLK => s_clk640_internal, -- 1-bit output: Output I/O clock
-- LOCK => s_locked_bufpll, -- 1-bit output: Synchronized LOCK output
-- SERDESSTROBE => strobe_16x_logic_O, -- 1-bit output: Output SERDES strobe (connect to ISERDES2/OSERDES2)
-- GCLK => s_clk160_internal, -- 1-bit input: BUFG clock input
-- LOCKED => s_locked_pll, -- 1-bit input: LOCKED input from PLL
-- PLLIN => s_clk640 -- 1-bit input: Clock input from PLL
-- );
s_reset_pll <= Reset_i or s_logic_reset;
BUFG_inst: BUFG
port map (
I => s_clk320,
O => s_clk320_internal
);
-- BUFR_inst: BUFR
-- generic map (
-- BUFR_DIVIDE => "4"
-- )
-- port map (
-- I => s_clk160_internal,
-- CE => '1',
-- CLR => '0',
-- O => ryanclock
-- );
-- BUFG_inst2: BUFG
-- port map (
-- I => ryanclock,
-- O => strobe_16x_logic_O -- Not sure this is actually a strobe... Check
-- );
-----------------------------------------------
clk_8x_logic_o <= s_clk320_internal;
DUT_clk_o <= s_DUT_clk;
DUT_clk_o <= s_DUT_clk;
-- Generate a strobe signal every 4 clocks.
-- Can't use a clock signal as a combinatorial signal. Hence the baroque
-- method of generating a strobe. Add a mechanism to restart if the '1' gets
-- lost ....
------------------
generate_4x_strobe: process (s_clk160_internal)-- , s_clk40_out)
-- Generate a strobe signal for 160MHz clock
generate_4x_strobe: process (s_clk160_internal, s_clk40)
begin -- process generate_4x_strobe
if rising_edge(s_clk160_internal) then
if s_logic_reset = '1' then
s_strobe_generator <= "1000";
s_logic_clk_generator <= "1100";
--s_strobe160 <= "1000000000000000";
elsif (s_locked_pll ='1') then
s_strobe_generator <= s_strobe_generator(2 downto 0) & s_strobe_generator(3); -- <- bit shift left
s_logic_clk_generator <= s_logic_clk_generator(2 downto 0) & s_logic_clk_generator(3); -- <- bit shift left
--s_strobe160 <= s_strobe160(14 downto 0) & s_strobe160(15);
end if;
end if;
if rising_edge(s_clk160_internal) then
s_clk40_delayed_160 <= s_clk40_delayed_160(s_clk40_delayed_160'left-1 downto 0) & s_clk40;
strobe_4x_logic_o <= s_clk40_delayed_160(s_clk40_delayed_160'left-1) and not s_clk40_delayed_160(s_clk40_delayed_160'left);
end if;
end process generate_4x_strobe;
strobe_4x_logic_o <= s_strobe_generator(3); -- Every 4 clocks this gets to 1 for one pulse
s_clk40_out <= s_logic_clk_generator(3); -- Every 4 clocks this gets to 1 for two pulses (so half F of the original clock? But then it is a clk80 not clk40.) Not used it seems.
---------------
generate_8x_strobe: process (s_clk320_internal)
begin
if rising_edge(s_clk320_internal) then
if s_logic_reset = '1' then
s_strobe160 <= "1000000000000000";
--s_strobe_generator <= "1111000000000000";--
--s_logic_clk_generator <= "1111111100000000";--
elsif (s_locked_pll ='1') then
s_strobe160 <= s_strobe160(14 downto 0) & s_strobe160(15);
--s_strobe_generator <= s_strobe_generator(14 downto 0) & s_strobe_generator(15); --
--s_logic_clk_generator <= s_logic_clk_generator(14 downto 0) & s_logic_clk_generator(15); -- <- bit shift left
end if;
end if;
-- Generate a strobe signal for 160MHz clock
generate_8x_strobe: process (s_clk160_internal, s_clk40)
begin -- process generate_4x_strobe
if rising_edge(s_clk320_internal) then
s_clk40_delayed_320 <= s_clk40_delayed_320(s_clk40_delayed_320'left-1 downto 0) & s_clk40;
strobe_8x_logic_o <= s_clk40_delayed_320(s_clk40_delayed_320'left-1) and not s_clk40_delayed_320(s_clk40_delayed_320'left);
end if;
end process generate_8x_strobe;
strobe_8x_logic_o <= s_strobe160(15);
--strobe_4x_logic_o <= s_strobe_generator(15); --
--s_clk40_out <= s_logic_clk_generator(15); --
-- buffer 160MHz (4x) clock
......@@ -327,15 +238,16 @@ BEGIN
I => s_clk160);
clk_4x_logic_o <= s_clk160_internal;
-- -- buffer 40MHz (1x) clock
-- --------------------------------------
-- clk40_o_buf : BUFG
-- port map(
-- O => s_clk40_internal,
-- I => s_clk40);
-- clk_logic_o <= s_clk40_out;
-- buffer 320MHz (8x) clock
--------------------------------------
clk320_o_buf: BUFG
port map (
I => s_clk320,
O => s_clk320_internal
);
clk_8x_logic_o <= s_clk320_internal;
END ARCHITECTURE rtl;
......@@ -51,7 +51,7 @@ use work.ipbus.ALL;
entity top is
generic(
constant FW_VERSION : unsigned(31 downto 0):= X"1e000022"; -- Firmware revision. Remember to change this as needed.
constant FW_VERSION : unsigned(31 downto 0):= X"1e000023"; -- Firmware revision. Remember to change this as needed.
g_NUM_DUTS : positive := 4; -- <- was 3
g_NUM_TRIG_INPUTS :positive := 6;-- <- was 4
g_NUM_EDGE_INPUTS :positive := 6;-- <-- was 4
......@@ -551,8 +551,8 @@ begin
DUT_clk_o => open,
logic_clocks_locked_o => leds(3),
logic_reset_o => logic_reset
);
);
----------------------------------------------
I5 : triggerInputs_newTLU
GENERIC MAP (
......
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