Up down counter with two clocks?

H

Hawker

Forgive me I am a VHDL novice at best. Trying to get though this CPLD
design as best I can and could use some help. I am trying to get this
working on CoolRunnerII CPLD.

I have an up down counter that counts up under one stimuli's and down on
another. No matter how I play with the VHDL I get an warning that it
can't be synthesize or it can't have two clocks.

The current code looks like this
address_counter: process (addr_counter, FX2_MAN_nRESET, MI_CLK_PIXEL,
FX2_MA_CNT_nUPDN, FX2_MA_RD, nRESET )
begin
if FX2_MAN_nRESET = '0' or nRESET = '0' then
addr_counter <= "0000000000000000000000";

elsif rising_edge(MI_CLK_PIXEL)and FX2_MA_CNT_nUPDN
= '0' AND MI_LINE_VALID = '0' AND MI_FRAME_VALID = '0' then -- Data in
to PSRAM
addr_counter <= addr_counter + 1;
elsif rising_edge(FX2_MA_RD) then
-- Data out to FX2
addr_counter <= addr_counter - 1;

end if;
end process address_counter;


Alternitivly we can frame this with FX2_MA_CNT_nUPDN since we would only
count up on MI_CLK_PIXEL if low and down on FX2_MA_RD if high.

Thanx
Hawker
 
H

Hawker

I think my problem is that for the down counter there is no clock.
This is an address counter for a PSRAM.

Basically this design clocks from a device to a buffer PSRAM. This is
controlled by a clock from the device (which is in master mode). The
data then clocks out of the buffer PSRAM int a USB 1.1 chip at slower
speed. The USB becomes the master then and uses the read line to clock
the counter. In this mode the clock from the original device is not part
of the equation and hence not used to clock this.

So in essence when clocked up there is one clock and when clocked down
there is another clock. Perhaps I need to create an internal gated clock
with the two clocks somewhere else and use that? I am not exactly sure
how to do that though.

I think this is the problem but I don't know how to get around this.
 
P

Peter

Forgive me I am a VHDL novice at best. Trying to get though this CPLD
design as best I can and could use some help. I am trying to get this
working on CoolRunnerII CPLD.

I have an up down counter that counts up under one stimuli's and down on
another. No matter how I play with the VHDL I get an warning that it
can't be synthesize or it can't have two clocks.

The current code looks like this
address_counter: process (addr_counter, FX2_MAN_nRESET, MI_CLK_PIXEL,
FX2_MA_CNT_nUPDN, FX2_MA_RD, nRESET )
begin
if FX2_MAN_nRESET = '0' or nRESET = '0' then
addr_counter <= "0000000000000000000000";

elsif rising_edge(MI_CLK_PIXEL)and FX2_MA_CNT_nUPDN
= '0' AND MI_LINE_VALID = '0' AND MI_FRAME_VALID = '0' then -- Data in
to PSRAM
addr_counter <= addr_counter + 1;
elsif rising_edge(FX2_MA_RD) then
-- Data out to FX2
addr_counter <= addr_counter - 1;

end if;
end process address_counter;

Alternitivly we can frame this with FX2_MA_CNT_nUPDN since we would only
count up on MI_CLK_PIXEL if low and down on FX2_MA_RD if high.

Thanx
Hawker


Something like this perhaps:

counter: process (clk,res) -- Only clk and res
begin
if res = '1' then -- Async reset
addr_counter <= (others => '0');
elsif rising_edge(clk) then -- No gated clock
if up = '1' then
addr_counter <= addr_counter + 1;
elsif down = '1' then
addr_counter <= addr_counter - 1;
end if;
end if;
end process counter;

/Peter
 
K

kennheinrich

Something like this perhaps:

counter: process (clk,res) -- Only clk and res
begin
if res = '1' then -- Async reset
addr_counter <= (others => '0');
elsif rising_edge(clk) then -- No gated clock
if up = '1' then
addr_counter <= addr_counter + 1;
elsif down = '1' then
addr_counter <= addr_counter - 1;
end if;
end if;
end process counter;

/Peter

This looks reasonable for a counter. You've drawn one with an asynch
reset, so obviously you will need to take care to deassert the reset
line synchronously to the clock to avoid timing violations and race
conditions, which can happen should you deassert the reset line close
to the clock while one of the increment signals is active.

The root of the complexity in your design is that there are two clock
domains that need to share one resource (PSRAM). Gated clocks are an
option but you must be exceptionally careful with your transition,
because if you generate runt pulses you will (at best) double-
increment your addresses, and (at worst) cause multiple setup-hold
violations which can throw any connected logic into metastable or
unknown states.

One other alternative solution is to use just one clock (the higher of
the two) for the control logic and PSRAM address generation, but pass
the "increment" signal from the slow clock to the fast clock with a
standard clock crosser. Then all your control logic always runs on
one clock, your timing is guaranteed to be met, and you just have to
focus on getting the timing right on one little section (the clock
crosser). This is easier when the one clock is many time faster than
the other, and you can pipeline things a little.

Another possible (but more brute force) approach is to duplicate the
counters (one running at clk1, one at clk2) and mux the whole output.
But then you may still have to load the one from the other, and this
again involves the clock crossing.

You can shuffle the clock crossing around, but you will have to solve
it somewhere. Typically, crossings are dangerous and often poorly
implemented, and so you're best off to isolate the crossing to the
smallest and simplest piece of logic possible. That's why I like the
single-clock approach.

But, as with all things, whatever works for you...

HTH,

- Kenn
 
P

Peter

Something like this perhaps:

counter: process (clk,res) -- Only clk and res
begin
if res = '1' then -- Async reset
addr_counter <= (others => '0');
elsif rising_edge(clk) then -- No gated clock
if up = '1' then
addr_counter <= addr_counter + 1;
elsif down = '1' then
addr_counter <= addr_counter - 1;
end if;
end if;
end process counter;

/Peter- Dölj citerad text -

- Visa citerad text -

Sorry, didnt notice your posting #3 about two clocks.
 

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,777
Messages
2,569,604
Members
45,227
Latest member
Daniella65

Latest Threads

Top