synchroniser - hold time is not sustained

V

Valentin Tihomirov

Guest
I have an example of synchronizer from one opencore project. In attempt to
understand the principle of its operation I have simulated it and encoutered
that one of the flipflops is feed '1' during SU and '0' during HOLD. WebPack
ModelSim asserts '0' to the FF after all. Is it normal?

entity synchroniser is
port (
C1 : in std_logic;-- Asynchronous signal
C : in std_logic;-- Clock
O : out std_logic);-- Synchronised signal
end synchroniser;

architecture Behaviour of synchroniser is
signal C1A : std_logic;
signal C1S : std_logic;
signal R : std_logic;
begin
RiseC1A : process(C1,R)
begin
if Rising_Edge(C1) then
C1A <= '1';
end if;
if (R = '1') then
C1A <= '0';
end if;
end process;

SyncP : process(C,R)
begin
if Rising_Edge(C) then
if (C1A = '1') then
C1S <= '1';
else C1S <= '0';
end if;
if (C1S = '1') then
R <= '1';
else R <= '0';
end if;
end if;
if (R = '1') then
C1S <= '0';
end if;
end process;
O <= C1S;
end Behaviour;


Is simulated with the following test bench. I pulse async input c1 for 1 ns.
This activates synchronizer's O for a 1 period of C. But I do not understand
the behaviour when C1S is '1' and C is rising. This activates R that clears
C1A (which is input of C1S) in turn. We get the condition where C1A is '1'
during SETUP and it is '0' during HOLD.

tb : PROCESS
BEGIN
C1 <= '0';
wait for 70 ns;
C1 <= '1';
wait for 1 ns;
C1 <= '0';
wait; -- will wait forever
END PROCESS;

CLOCK : process
begin
C <= '0';
wait for 10 ns;
C <= '1';
wait for 10 ns;
end process;
 
Hi Valentin,

Not exactly an answer to your question but this code looks a little weird to
me. I don't think it is synthesizable (and perhaps it should be) as the
reset inputs in both processes are not prioritirized. I would do something
like this:

architecture Behaviour of synchroniser is
signal C1A : std_logic;
signal C1S : std_logic;
signal C1S_FF : std_logic:='0';
signal R : std_logic;
begin
RiseC1A : process(C1,C1S)
begin
if (C1S = '1') then
C1A <= '0';
elsif Rising_Edge(C1) then
C1A <= '1';
end if;
end process;

SyncP : process(C,R)
begin
if (C1S_FF = '1') then
C1S <= '0';
elsif Rising_Edge(C) then
if (C1A = '1') then
C1S <= '1';
end if;
end if;
end process;

RstP: process(C)
begin
if rising_edge(C) then
C1S_FF <= C1S;
end if;
end process;

O <= C1S;

end Behaviour;


/Mikhail
 
Valentin Tihomirov wrote:
I have an example of synchronizer from one opencore project. In attempt to
understand the principle of its operation I have simulated it and encoutered
that one of the flipflops is feed '1' during SU and '0' during HOLD. WebPack
ModelSim asserts '0' to the FF after all. Is it normal?
It looks like this code will produce synchronous pulse
soon after the rising edge of C1.

However, I don't think this synchronizer is worthy
of much study as it has no reset and uses the input
as a clock.

A more conventional design would include a synchronous
shift register with a synchronous rising edge decode
of the third and fourth stages.

-- Mike Treseler
 

Welcome to EDABoard.com

Sponsor

Back
Top