Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

signal between two clock domains. (code verification)

Status
Not open for further replies.

FixitFast

Junior Member level 2
Joined
Feb 6, 2013
Messages
20
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,462
hi all

I have one signal that works in a module where there are 2 clocks of different frequencies. Actually I had and have been using the code for single pulse if it is between two clock domains, but now this signal is not a pulse, but a signal that remains HIGH for longer period of time (shows active state of an other module). The strategy I have used below is that I have taken AND of the pulse_in (clk domain1) and pulse_out(clock domain 2) I have shared the code as well. But I am not sure if it works fine or not. although simulation results are fine as shown in figure as signal named 'common' is ANDed signal. should this technique work for both domains without metastability?

NOTE: pulsein and pulseout are not actually pulses, they are signals that remain HIGH or LOW, actually I modified the pulse related code but did not change the names of the signals

You can find in code statement
common <= pulseout and pulsein;

Code:
--all libraries not shown here

entity pulse2pulse is
port (
   in_clk      :in std_logic;
   out_clk     :in std_logic;
   rst         :in std_logic;
   pulsein     :in std_logic;
   inbusy      :out std_logic;
   pulseout    :inout std_logic;
   common 	   : out std_logic
   );
end pulse2pulse;

architecture syn of pulse2pulse is

signal out_set       :std_logic;
signal out_set_prev  :std_logic;
signal out_set_prev2 :std_logic;
signal in_set        :std_logic;
signal outreset      :std_logic;
signal in_reset      :std_logic;
signal in_reset_prev :std_logic;
signal in_reset_prev2:std_logic;

--********************************
begin
--********************************

common <= pulseout and pulsein;

in_proc:process(in_clk,rst)
begin
   if(rst = '1') then
      in_reset      <= '0';
      in_reset_prev <= '0';
      in_reset_prev2<= '0';
      in_set        <= '0';

   elsif(in_clk'event and in_clk = '1') then
      --regitser a pulse on the pulse in port
      --reset the signal when the ouput has registerred the pulse
      -- if (in_reset_prev = '1' and in_reset_prev2 = '1') then
         -- in_set <= '0';
      -- elsif (pulsein = '1') then
         -- in_set <= '1';
      -- end if;
      if(pulsein = '1') then
         in_set <= '1';
	  else
	     in_set <= '0';
      end if;

      --register the reset signal from the other clock domain
      --three times. double stage synchronising circuit
      --reduces the MTB
      in_reset       <=  outreset;
      in_reset_prev  <= in_reset;
      in_reset_prev2 <= in_reset_prev;

   end if;
end process in_proc;

out_proc:process(out_clk,rst)
begin
   if(rst = '1') then
      out_set       <= '0';
      out_set_prev  <= '0';
      out_set_prev2 <= '0';
      outreset      <= '0';
      pulseout      <= '0';
   elsif(out_clk'event and out_clk = '1') then
      --generate a pulse on the outpput when the
      --set signal has travelled through the synchronising fip flops
      -- if (out_set_prev = '1' and out_set_prev2 = '0') then
      if (out_set_prev = '1') then
         pulseout <= '1';
      else
         pulseout <= '0';
      end if;

      --feedback the corret reception of the set signal to reset the set pulse
      -- if (out_set_prev = '1' and out_set_prev2 = '1') then
      if (out_set_prev = '1' and out_set_prev2 = '1' and out_set = '0') then
         outreset <= '1';
      elsif (out_set_prev = '0' and out_set_prev2 = '0') then
         outreset <= '0';
      end if;

      --register the reset signal from the other clock domain
      --three times. double stage synchronising circuit
      --reduces the MTB
      out_set        <= in_set;
      out_set_prev   <= out_set;
      out_set_prev2  <= out_set_prev;

   end if;
end process out_proc;

---------------------------------------
--asynchronous mapping
---------------------------------------
 -- inbusy <= in_set or in_reset_prev;
 inbusy <= in_set or out_set_prev2;

end syn;

simulation.JPG

- - - Updated - - -

or is the following approach better

Code:
process(out_clk, rst )
begin
if(rst = '1') then
	pulse_out<= '0';
elsif(rising_edge(out_clk)) then
	if(pulse_in= '1') then
	pulse_out<= '1';
	else
	pulse_out<= '0';
	end if;

end if;
end process;


pulse_common <=pulse_in and pulse_out;

-- where :
-- pulse_in is clock domain 1
-- pulse_out is then for clock domain 2
-- pulse_common is and between two signals and used in both domains combined as follows

...
if(rising_edge(clk1)) then
if(pulse_common) then
 ...
end if;

end if;


...
if(rising_edge(clk2)) then
if(pulse_common) then
 ...
end if;

end if;
...
...
 
Last edited:

The second code example uses a signal that isn't guaranteed to be synchronous to either clock domain. So you'll have violations on setup or hold.
 
Yes you are right, later I realize this thing when I see deeply...

what to do then...Is this thing (simple 2 FF synchronizer for removing metastability) all right

in_proc:process(in_clk,rst)
begin
if(rst = '1') then
in_set <= '0';

elsif(in_clk'event and in_clk = '1') then

if(pulsein = '1') then
in_set <= '1';
else
in_set <= '0';
end if;


end if;
end process in_proc;

out_proc:process(out_clk,rst)
begin
if(rst = '1') then
out_set <= '0';
out_set_prev <= '0';
pulseout <= '0';
elsif(out_clk'event and out_clk = '1') then

if (out_set_prev = '1') then
pulseout <= '1';
else
pulseout <= '0';
end if;

out_set <= in_set;
out_set_prev <= out_set;

end if;
end process out_proc;
 

Status
Not open for further replies.

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top