R
Rob Gaddi
Guest
I'm working on a Spartan 3 design and trying to figure out how, if at
all, I can constrain what I'm looking for without resorting to hand
placement and directed routing.
I've got an analog pulse that feeds 4 comparators with different
thresholds. This gives me 4 pulses of which each narrower one is
contained entirely in time by each wider one, like the side view of the
Towers of Hanoi experiment. The widest will be 3-4 ns, the narrowest
will be narrow enough to not consistently be able to trip the internal
flops. They'll be coming in at up to 80 MHz.
Given that this is pretty fast for an S3, I've lit on the idea of using
each pulse to clock a T-flop, then resynchronize the output of the T at
200 MHz into an XOR change detector; the classic pulse-toggle-pulse
domain crosser but directly clocked rather than clock enabled. Code
(untested) at the end of this message.
So I've got a 2 ns event (rising edges only) and a 5 ns clock period. I
need to make sure that all of my resynchronized pulses come out during
clock cycle n or n+1. Which, so near as I can figure, means that I want
to have no more than 3 ns of routing delay skew on these signals, from
the pins through the Ts to the D input on the first synchronizer stage.
Anyone have the foggiest how to bully the tools into pulling this off?
Thanks,
Rob
--------
entity fast_rising_edge_det is
generic (
SYNC_STAGES : positive := 2;
REGISTER_OUTPUT : boolean := true
); -- Number of delay flip-flops
port (
edge : in std_logic; -- Edge to be detected
clk : in std_logic; -- Clock to synchronize the output to.
pulse_out : out std_logic); -- Output pulse for the rising edge.
end entity fast_rising_edge_det;
architecture Behavioral of fast_rising_edge_det is
signal toggle : std_logic := '0';
signal delay_stages : std_logic_vector(SYNC_STAGES-1 downto 0)
:= (others => ''0'');
signal old_val : std_logic := '0';
signal change : std_logic;
begin -- architecture Behavioral
TFLOP : toggle <= not toggle when rising_edge(edge);
DLINE : process (clk) is
begin -- process
if rising_edge(clk) then -- rising clock edge
if (SYNC_STAGES = 1) then
delay_stages(0) <= toggle;
else
delay_stages <= delay_stages(SYNC_STAGES-2 downto 0) & toggle;
end if;
end if;
old_val <= delay_stages(delay_stages'high);
end process;
change <= old_val xor delay_stages(delay_stages'high);
REG_OUT : if (REGISTER_OUTPUT) generate
pulse_out <= change when rising_edge(clk);
end generate REG_OUT;
NOREG_OUT : if (not REGISTER_OUTPUT) generate
pulse_out <= change;
end generate NOREG_OUT;
end architecture Behavioral;
--------
--
Rob Gaddi, Highland Technology
Email address is currently out of order
all, I can constrain what I'm looking for without resorting to hand
placement and directed routing.
I've got an analog pulse that feeds 4 comparators with different
thresholds. This gives me 4 pulses of which each narrower one is
contained entirely in time by each wider one, like the side view of the
Towers of Hanoi experiment. The widest will be 3-4 ns, the narrowest
will be narrow enough to not consistently be able to trip the internal
flops. They'll be coming in at up to 80 MHz.
Given that this is pretty fast for an S3, I've lit on the idea of using
each pulse to clock a T-flop, then resynchronize the output of the T at
200 MHz into an XOR change detector; the classic pulse-toggle-pulse
domain crosser but directly clocked rather than clock enabled. Code
(untested) at the end of this message.
So I've got a 2 ns event (rising edges only) and a 5 ns clock period. I
need to make sure that all of my resynchronized pulses come out during
clock cycle n or n+1. Which, so near as I can figure, means that I want
to have no more than 3 ns of routing delay skew on these signals, from
the pins through the Ts to the D input on the first synchronizer stage.
Anyone have the foggiest how to bully the tools into pulling this off?
Thanks,
Rob
--------
entity fast_rising_edge_det is
generic (
SYNC_STAGES : positive := 2;
REGISTER_OUTPUT : boolean := true
); -- Number of delay flip-flops
port (
edge : in std_logic; -- Edge to be detected
clk : in std_logic; -- Clock to synchronize the output to.
pulse_out : out std_logic); -- Output pulse for the rising edge.
end entity fast_rising_edge_det;
architecture Behavioral of fast_rising_edge_det is
signal toggle : std_logic := '0';
signal delay_stages : std_logic_vector(SYNC_STAGES-1 downto 0)
:= (others => ''0'');
signal old_val : std_logic := '0';
signal change : std_logic;
begin -- architecture Behavioral
TFLOP : toggle <= not toggle when rising_edge(edge);
DLINE : process (clk) is
begin -- process
if rising_edge(clk) then -- rising clock edge
if (SYNC_STAGES = 1) then
delay_stages(0) <= toggle;
else
delay_stages <= delay_stages(SYNC_STAGES-2 downto 0) & toggle;
end if;
end if;
old_val <= delay_stages(delay_stages'high);
end process;
change <= old_val xor delay_stages(delay_stages'high);
REG_OUT : if (REGISTER_OUTPUT) generate
pulse_out <= change when rising_edge(clk);
end generate REG_OUT;
NOREG_OUT : if (not REGISTER_OUTPUT) generate
pulse_out <= change;
end generate NOREG_OUT;
end architecture Behavioral;
--------
--
Rob Gaddi, Highland Technology
Email address is currently out of order