Making a timer out of TFFs

L

laserbeak43

Hello, I've tried making a 16 bit timer out of TFFs using this code:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
entity myTFF is
port( T, Clk, Reset : in std_logic;
Q : out std_logic
);
end myTFF;

architecture behavioral of myTFF is

signal buf : std_logic;

begin

process(T, Clk, Reset)
begin

if(reset = '1') then
buf <= '0';
end if;

if(Clk = '1') then
if(T = '1')then
buf <= (NOT buf);
end if;
end if;

end process;

Q <= buf;

end behavioral;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
entity TFFcounter16bit is

port ( enable, clk, rst : in std_logic;
Qpin : out unsigned(15 downto 0)
);

end TFFcounter16bit;

architecture wowee of TFFcounter16bit is

signal Qout : unsigned(15 downto 0);

begin

myTFF0 : entity work.myTFF port map( enable, clk, rst, Qout(0));
myTFF1 : entity work.myTFF port map( (enable AND Qout(0)), clk, rst,
Qout(1));
myTFF2 : entity work.myTFF port map( ((enable AND Qout(0)) AND
Qout(1) ), clk, rst, Qout(2));
etc... all the way town to myTFF15

Qpin <= Qout;

end wowee;
///////////////////////////////////////////
but it works terribly. Could someone give me an example of how to do
this? Just in case you're wondering, this is not schoolwork It's from
the Altera Labs. DE2 Lab4 part1 to be exact.

thanks
Malik
 
J

Jonathan Bromley

I've tried making a 16 bit timer out of TFFs using this code:
but it works terribly.

Ye gods and little fishes, what on earth would you
want to do that for? It's horrible! All that
soldering.... all those wires.... yuck. Nearly
twenty years ago I got away from all that junk by
learning Verilog and VHDL, and using synthesis.

Understood that you might want to work through some lab
exercises, but what is the point of anything so detached
from common-sense?

And what, precisely, does "works terribly" mean? If you
get the ridiculous wiring-knitting just right, it should
work the same way as any other synchronous ripple counter.
Get it wrong and it'll be broken.

Oh, and your toggle FF model is garbage too. T should
not be in its sensitivity list. The clock test should
be an "elsif" on the end of the reset test, not a
separate "if". The clock test should be
elsif Clk'event and Clk='1'
or, better,
elsif rising_edge(Clk)

If that code came out of a book, junk the book and get
a decent one. If it didn't, get a book :)

cheers
 
L

laserbeak43

LOL!! wow, you're a colorful person. I can't remember where I got that
TFF from, so I've probably made it myself :/. and yeah stringing all
of that together really did suck, but it's what the project called for
me to do:
ftp://ftp.altera.com/up/pub/Altera_Material/QII_9.0/Digital_Logic/DE2/Laboratory_Exercises/VHDL/lab4_VHDL.pdf
Malik
 
J

Jonathan Bromley

ftp://ftp.altera.com/up/pub/Altera_Material/QII_9.0/Digital_Logic/DE2/Laboratory_Exercises/VHDL/lab4_VHDL.pdf

OK, maybe it's not so bad. At least they invite you to *compare*
it with Q<=Q+1; which is the non-demented way to do it.

I don't know about "colourful" but I do have a hidden kindly streak,
so here's a TFF for you...


process (Clk, nReset)
begin
if nReset = '0' then
tff <= '0'; -- async reset
elsif rising_edge(Clk) then
if T = '1' then
tff <= not tff;
end if;
end if;
end process;

And here's a cutesy-poo way to describe a bunch of
TFFs organised as a ripple counter like the nice
lab description:

signal Ctr: std_logic_vector(N-1 downto 0);
...
process (Clk, nReset)
variable ripple_enable: boolean;
begin
if nReset = '0' then
Ctr <= (others => '0');
elsif rising_edge(Clk) then
ripple_enable := (count_enable = '1');
for i in Ctr'reverse_range loop -- LSB first
if ripple_enable then
if Ctr(i) = '0' then
ripple_enable := false;
end if;
Ctr(i) <= not Ctr(i);
end if;
end loop;
end if;
end process;

Less yucky than the wires?
 
L

laserbeak43

LOL! Yes you are kind. Thanks.
BUT, that's the easy way to do it, and I think the point of the
exercise(i could be wrong) is to make you do it the hard way, forcing
you to use a instances of your TFF to string together a counter.
 
M

Mike Treseler

laserbeak43 said:
BUT, that's the easy way to do it, and I think the point of the
exercise(i could be wrong) is to make you do it the hard way, forcing
you to use a instances of your TFF to string together a counter.

Well, Jonathan gave you the T-flop process, so add an
architecture and entity so you can then instance
four of those in your top architecture.

It is a silly exercise for fpga synthesis because
1. The device primitives are LUTs and D-flops.
2. Synthesis makes the primitives irrelevant anyway.
3. The design intent of Q <= Q+1; is obscured by wires and T-Flops.

Jonathan's solution meets the spirit of the problem
without all those signals.

-- Mike Treseler
 
B

backhus

Hello, I've tried making a 16 bit timer out of TFFs using this code:
/////////////////////////////////////////////////////////////////////////////////////////////////////////////
entity myTFF is
        port( T, Clk, Reset     : in std_logic;
                        Q                       : out std_logic
        );
end myTFF;

architecture behavioral of myTFF is

        signal buf : std_logic;

begin

        process(T, Clk, Reset)
        begin

                if(reset = '1') then
                        buf <= '0';
                end if;

                if(Clk = '1') then
                        if(T = '1')then
                                buf <= (NOT buf);
                        end if;
                end if;

        end process;

        Q <= buf;

end behavioral;
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
entity TFFcounter16bit is

        port (  enable, clk, rst : in std_logic;
                        Qpin    : out unsigned(15 downto 0)
        );

end TFFcounter16bit;

architecture wowee of TFFcounter16bit is

        signal Qout : unsigned(15 downto 0);

begin

        myTFF0  : entity work.myTFF port map( enable, clk, rst, Qout(0));
        myTFF1  : entity work.myTFF port map( (enable AND Qout(0)), clk, rst,
Qout(1));
        myTFF2  : entity work.myTFF port map( ((enable AND Qout(0)) AND
Qout(1) ), clk, rst, Qout(2));
        etc... all the way town to myTFF15

        Qpin <= Qout;

end wowee;
///////////////////////////////////////////
but it works terribly. Could someone give me an example of how to do
this? Just in case you're wondering, this is not schoolwork It's from
the Altera Labs. DE2 Lab4 part1  to be exact.

thanks
Malik

Hi Malik,
you saíd that the example come sfrom some "Altera Labs. DE2 Lab4
part1" assignment.
I have searched this place and found several assignments labeled like
you mentioned:
ftp://ftp.altera.com/up/pub/Altera_Material/QII_9.0/
Unfortunately none of them has a T-FF counter in it.

The topics of these labs range from digital basics to NIOS-Application
training.
So what is the intended teaching purpose of the example you presented
here.
Obviously, it's not "The Art of VHDL".

Have a nice synthesis
Eilert
 
B

backhus

On 6/4/2010 12:52 PM, Jonathan Bromley wrote:
 >
 > [snip]




And here's a cutesy-poo way to describe a bunch of
TFFs organised as a ripple counter like the nice
lab description:
   signal Ctr: std_logic_vector(N-1 downto 0);
   ...
   process (Clk, nReset)
     variable ripple_enable: boolean;
   begin
     if nReset = '0' then
       Ctr<= (others =>  '0');
     elsif rising_edge(Clk) then
       ripple_enable := (count_enable = '1');
       for i in Ctr'reverse_range loop -- LSB first
         if ripple_enable then
           if Ctr(i) = '0' then
             ripple_enable := false;
           end if;
           Ctr(i)<= not Ctr(i);
         end if;
       end loop;
     end if;
   end process;
Less yucky than the wires?

Actually had to do something very similar to that a while back for an
application that really really really required that I convince the tools
to build a real ripple counter (each flop clocked from the falling edge
of the output of the previous).  Nothing short of directly instantiating
the flop out of UNISIM and wiring it up myself would coerce it into working.

Hi Rob,
while I'm sure that it is possible to describe this in behavioral
VHDL,
instantiating (especially with a generate loop) is much simpler.

Just out of curiosity: What kind of application demanded the use of
such an asynchronous counter.
Maliks example is still about a synchronous one, even if it uses T-FFs
to simplify the combinatorical stuff.

Have a nice synthesis
Eilert
 
J

Jeff Cunningham

Just out of curiosity: What kind of application demanded the use of
such an asynchronous counter.

Consider a small CPLD with a 100 Mhz state machine. Now I want to add a
LED that blinks at a human observable rate. A giant synchronous counter
would waste a whole bunch of product terms and probably be the timing
critical path. A ripple counter is perfect for this situation.

-Jeff
 
K

KJ

Asynchronous frequency counter.  A ripple counter only has a single
point of entry,

Not usually...we'll come back to that
so you can gate the external input signal at that very
first flop.  Turn it off, wait long enough to be sure that the ripple's
worked its way through,

Not sure that you can figure out out how long is 'long enough' by
measuring something in the system...which means you have to rely on
the timing reports
read it out,
raise then lower the asynch clear,
Async clear...sounds like seconc point of entry.

wait a bit more, and start it up again.  You can measure frequencies up
to the individual flop toggle speed of the FPGA.

Unless you have a way to measure when the system has settled, then you
can only reliably measure up to the frequency that the timing reports
allow.

Depending on what you're doing with the frequency measurements, an
LFSR counter would work much faster than a ripple counter...you lose
the binary number interpretation of the bits of the counter though.

KJ
 
K

KJ

Consider a small CPLD with a 100 Mhz state machine. Now I want to add a
LED that blinks at a human observable rate. A giant synchronous counter
would waste a whole bunch of product terms and probably be the timing
critical path. A ripple counter is perfect for this situation.

If the blink rate is a fixed (or a set of fixed) rates that are known
ahead of time, then an LFSR counter is likely the better choice. The
product term usage would be darn near identical, clock routing and
timing is better.

If the blink rate needs to be externally programmable, then the LFSR
becomes a bit of a chore for whatever it is that programs it since
there needs to be an algorithm to translate from the desired blink
rate to the appropriate count value.

KJ
 
B

backhus

If the blink rate is a fixed (or a set of fixed) rates that are known
ahead of time, then an LFSR counter is likely the better choice.  The
product term usage would be darn near identical, clock routing and
timing is better.

If the blink rate needs to be externally programmable, then the LFSR
becomes a bit of a chore for whatever it is that programs it since
there needs to be an algorithm to translate from the desired blink
rate to the appropriate count value.

KJ

Hi,
so, as suspected, the only meaningful use for asynchronous counters is
frequency dividing.
Given some stable freqency on the input, the output FF has a 50% duty
cycle, without adding extra logic.

KJ,How about the LFSR Counters? They are most commonly used for Pseudo
Random Number generation.
How does one get a 50% duty cycle signal out of these? Is there some
nice solution?

Johnson Counters offer both, being syncronous and having a 50% duty
cycle(on every bit).
But their counting length only increases with 2*N instead of the 2^N
increase of ordinary counters. (N=Number of bits)

Have a nice synthesis
Eilert
 
K

KJ

Would you implement your LFSR counter as a shift register with the input
signal driving all of the flops independently?  The skew there's going
to be fatal;

I have never found it to be fatal. A hypothetical 32 bit counter
running at 1 GHz can time things up to 4.2 seconds with 1 ps
resolution...now maybe if I had a need for a 786 bit LFSR like whygee
posted (*1) the loading could get to be an issue, but since 1 GHz and
4.2 seconds at 1 ps accuracy are beyond where I've had a need, loading
hasn't been a problem.

That 786 bit counter though would allow me to measure 1.28E220 years
to a ps (if I did the math right). But I'm betting the device would
have long since have returned to silicon, copper and other elements
long before that.
all you need is one setup time violation one time and
everything goes to hell.

That's always the case...not unique to any form of counter
With the ripple counter, I'll say again, you can reliably measure up to
the single flop toggle frequency.  What you're saying about having to
wait for the system to settle is a different issue.  The counter itself
can be clocked substantially faster than the overall system settling
time because you don't have to wait for the entire ripple to go through
in order to count; only to read/clear.  That happens on a different
timescale than the frequency counting itself does.

You're making an assumption about the timescales for counting and
reading always being different. Whether they are or not depends on
the application. For those cases where that assumption applies,
you're correct that a ripple counter might be the best candidate for
the implementation...also assuming you're in a device that supports
multiple clocks in the first place (flashing back to simple PLD
devices, 16V8, things like that...only as a reminder that the
implementation technology might be a limitation as well)

Kevin Jennings

(*1) http://groups.google.com/group/comp.lang.vhdl/browse_frm/thread/697d8a6d0769652b?hl=en#
 

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,763
Messages
2,569,562
Members
45,038
Latest member
OrderProperKetocapsules

Latest Threads

Top