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;
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;