Generating a trigger signal to align two processes running on different clocks

D

Divyang M

I'm having some trouble with a dual clock design that I am working on.
First the details of what I'm am trying to do:

I have a sys_clk and a fast_clk (where fast_clk is 4 times faster than
the sys_clk). I generate both these clocks using the altpll
megafunction from Altera and the clocks are synchronised.

So, for the part of my design which runs off the sys_clk I start as
follows :

process(start, reset, sys_clk)
begin
if (reset = '1') then -- asynchronous reset
...
else
if(sys_clk = '1' and sys_clk'event) then
if (start = '1') then
... whatever the process has to do..
end if;
end if;
end if;
end process;

which is fine.
NOTE : The 'start' signal is a physical button so may not be generated
with the rising edge but it is only detected at the rising edge (normal
to vhdl designs)

Now, for the part of my design that works on the fast_clk, I want this
process to start when the sys_clk process also sees the start signal.

To make this a little clearer, let T11, T21, T31,.. be the rising edge
of sys_clk and

T11, T12, T13, T14, T21, T22, T23, T24, T31, T32, ... be the rising
edges of the fast_clk

so that T11, T21, ... from both clocks coincide. The clocks are
guaranteed to be synchronised (atleast that's what the altpll claims so
I am believing that)

Now for the fast_clk processes if I use
process(start, reset, fast_clk)
begin
if (reset = '1') then -- asynchronous reset
...
else
if(fast_clk = '1' and fast_clk'event) then
if (start = '1') then
... whatever the process has to do..
end if;
end if;
end if;
end process;

then this might start at Tx1, Tx2, Tx3, or Tx4..it is not know..but
I want it to start at Tx1 so that it coincided with the start of the
process running on sys_clk.

So I've come up with the following:

process(fast_clk, start)
begin
if (fast_clk = '1' and fast_clk'event) then
if (sys_clk = '1' and sys_clk'event and start = '1') then
start_fast <= '1';
end if;
end if;
end process;

Then, I plan to use start_fast (instead of start) in the process
dependent on the fast_clk.

Can anyone please provide me a critique of this and if this will work?
Also, any other alternatives?

Thanks,
Divyang M.
 
D

Divyang M

Well, reading the topic on the reset signal below, I think generating a
synchronous start (sync'd on the rising edge of sys_clk, which means it
will also be sync'd with the rising edge of the fast_clk at T11) might
be a better idea.

But then, now my concern is that the start signal (if generated at T11)
will be seen by processes dependent on sys_clk at T21 and by processes
dependentent on fast_clk at T12. Therefore the start will again not be
aligned at Tx1. Here I am assuming that a signal generated at the
rising edge of a clk will only be seen by other processes at the next
rising edge. Is this true? OR Are the signals available
instantaneously?
 
C

Charles Bailey

I gather from your description that the rising edge of sys_clk coincides
with one of the rising edges of fast_clk and you want them to act on
"start" on the same rising edge.

I would suggest something like this:

SIGNAL start1x, start4x_2, start4x_3, start4x_4, start4x : std_logic;

sync_proc1: PROCESS
BEGIN
WAIT until sys_clk='1';
start1x <= start;
END PROCESS;

sync_proc4: PROCESS
BEGIN
WAIT until fast_clk='1';
start4x_2<= start1x;
start4x_3<= start4x_2;
start4x_4<= start4x_3;
END PROCESS;

start4x <= start1x and start4x_2 and start4x_3 and start4x_4;
-- start4x will be active for 1 4x clock cycle in the 4th quarter of the
1x clock period
-- fast_clk will act on it on its next rising edge, which should
coincide with the next
-- rising edge of sys_clk. sys_clk will act on start1x at the same
time; so both of
-- your processes start together.
-- (Note that I removed start from the sensitivity lists of your two
processes, because
-- start1x and start4x have already been synchronized with their
respective clocks.)

process(reset, sys_clk)
begin
if (reset = '1') then -- asynchronous reset
...
else
if(sys_clk = '1' and sys_clk'event) then
if (start1x = '1') then
... whatever the process has to do..
end if;
end if;
end if;
end process;

process(reset, fast_clk)
begin
if (reset = '1') then -- asynchronous reset
...
else
if(fast_clk = '1' and fast_clk'event) then
if (start4x = '1') then
... whatever the process has to do..
end if;
end if;
end if;
end process;


Hope this helps.
Charles Bailey
 
C

Charles Bailey

(Trying again... The synchronization in my previous post needs a little
refinement.)

I gather from your description that the rising edge of sys_clk coincides
with one of the rising edges of fast_clk and you want them to act on
"start" on the same rising edge.

I would suggest something like this:

SIGNAL start1x_1, start1x_2, start1x,
start4x_2, start4x_3, start4x_4, start4x_5, start4x : std_logic;

sync_proc1: PROCESS
BEGIN
WAIT until sys_clk='1';
start1x_1 <= start;
start1x_2 <= start1x_1;
END PROCESS;
start1x <= start1x_1 and not start1x_2;

sync_proc4: PROCESS
BEGIN
WAIT until fast_clk='1';
start4x_2<= start1x;
start4x_3<= start4x_2;
start4x_4<= start4x_3;
start4x_5<= start4x_4;
END PROCESS;
start4x <= start4x_4 and not start4x_5;
-- start4x will be active for 1 4x clock cycle in the 4th quarter of the
-- 1x clock period
-- fast_clk will act on it on its next rising edge, which should
-- coincide with the next rising edge of sys_clk.
-- sys_clk will act on start1x at the same time; so both of
-- your processes start together.
-- (Note that I removed start from the sensitivity lists of your two
-- processes, because start1x and start4x have already been
-- synchronized with their respective clocks.)

process(reset, sys_clk)
begin
if (reset = '1') then -- asynchronous reset
...
else
if(sys_clk = '1' and sys_clk'event) then
if (start1x = '1') then
... whatever the process has to do..
end if;
end if;
end if;
end process;

process(reset, fast_clk)
begin
if (reset = '1') then -- asynchronous reset
...
else
if(fast_clk = '1' and fast_clk'event) then
if (start4x = '1') then
... whatever the process has to do..
end if;
end if;
end if;
end process;


And, furthermore, since asynchronous resets are generally bad news, I
would restructure the whole thing, make the resets synchronous,
and combine all the latches that are set with the 1x clock into one
process and do the same for the 4x clock. Like this:


SIGNAL reset1x, reset4x,
start1x_1, start1x_2, start1x,
start4x_2, start4x_3, start4x_4, start4x_5, start4x : std_logic;

clk1x_proc: PROCESS
BEGIN
WAIT until sys_clk='1';
reset1x <= reset;
start1x_1 <= start;
start1x_2 <= start1x_1;
IF (reset1x = '1') then -- SYNCHRONOUS reset
...
else
if (start1x = '1') then
... whatever happens on the start cycle
else
... whatever happens on the other cycles
end if;
end if;
END PROCESS;
start1x <= start1x_1 and not start1x_2;

clk4x_proc: PROCESS
BEGIN
WAIT until fast_clk='1';
reset4x <= reset;
start4x_2<= start1x;
start4x_3<= start4x_2;
start4x_4<= start4x_3;
start4x_5<= start4x_4;
if (reset4x = '1') then -- SYNCHRONOUS reset
...
else
if (start4x = '1') then
... whatever happens on the start cycle
else
... whatever happens on the other cycles
end if;
end if;
END PROCESS;
start4x <= start4x_4 and not start4x_5;


Hope this helps.
Charles Bailey
 
D

Divyang M

Hello Charles,

I really appreciate your help with the syncronisation of the start
signal.
I tried your first suggestion (becuase the start signal stays active
throught)
and it seems to work.

Thank you,
Divyang M.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top