Re: Problem with simple VHDL piece of code



On Thu, 12 Jul 2007 11:18:18 -0700, Jaco
Naude <naude.jaco@xxxxxxxxx> wrote:

I'm wondering if any VHDL expert out there can tell me why the
following piece of code isn't working. It should be a simple clock
divider, enabling the CE signal on every counter'th pulse. However the
counter increase line counter := 1+ counter does not increment the
variable. If I change the 1 to for example 20 it stays 20 throughout
the simulation. I'm sure the input signals are correct... Any
suggestions would be helpful.

I'm fairly sure that it's the <= comparisons that are breaking
your design, but while we have the code in front of us there
are a few design style issues that might be worth pursuing.
Would it be fair to guess that you are by habit a software
person, moving into hardware? :-)

process (clk)
variable counter : integer :=0;

Initialisation doesn't usually work in hardware. Better
to use an explicit reset of some kind (as you have done).

begin
if (clk'event and clk = '1') then
counter_out <= counter;

I'm guessing this is just a diagnostic output, so that you
can easily see what "counter" is doing? Note that it lags
behind "counter" by one clock cycle.

if rst <= '1' then
counter := 0;
ce_out <= '1';
end if;

OK. Synchronous reset; I'm sure that's what you intended,
but it's worth checking...

if start <= '1' and rst <= '0' then

if rst='1' then
....reset actions
elsif start='1' then
....main code body
end if

would perhaps have been neater, and easier to follow.

if counter < counter_top + 1 then

Again I'm guessing. counter_top is an incoming signal, perhaps
the contents of a writeable register? This comparison is rather
expensive in hardware, since you are building an incrementer
and a magnitude comparator. For dividers like this, it's
almost always better to preset the counter to the limit
value and then count it down until it reaches a constant
(1 or 0, in most situations).

ce_out <= '0';
counter := 1 + counter;

Are you happy for ce_out to freeze at '1' if someone drops the
'start' signal at an inopportune moment? It may be better to
default ce_out to '0' and set it to '1' only for a single clock
when the wraparound occurs.

else
counter := 0;
ce_out <= '1';
end if;
else
ce_out <= '1';
end if;
end if;
end process;

Finally, your integer counter seems to be unconstrained;
consequently, it will probably be synthesised to 32 bits.
There are various opinions about this, but my own practice
is always to use the numeric_std UNSIGNED or SIGNED vector
types rather than integers.

If I take all my own advice, I end up with something like
this:

constant counter_bits: positive := 16; -- or maybe a generic
signal counter_top: unsigned(counter_bits-1 downto 0);
signal ce_out, start, rst: std_logic;
....
process (clk)
variable counter: unsigned(counter_top'range);
begin
if rising_edge(clk) then
ce_out <= '0';
if rst = '1' then
ce_out <= '1';
counter := counter_top;
elsif start = '1' then
if counter = 0 then
ce_out <= '1';
counter := counter_top;
else
counter := counter - 1;
end if;
end if;
end process;

Note that this generates ce_out with a period of
(counter_top + 1) cycles. If you want the period
to be exactly (counter_top) then you should test
"if counter=1" for the wraparound. The limit
comparator is now trivial, and involves no arithmetic.

Also, note that ce_out will be asserted for the whole
time that rst is asserted. If you don't want that, it
might be better to reset the counter to 1 so that ce_out
is asserted on the first clock after reset is released.

I hope it's clear from the above that you have a lot of
choices, and my suggestions may or may not be useful
depending on what else is happening in your system.

HTH
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@xxxxxxxxxxxxx
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
.



Relevant Pages

  • Re: Mixed clocked/combinatorial coding styles
    ... I wouldn't use a device input that performs a device wide reset ... as a clock input had better be able to cope with the clock shutting ... The outputs of the shift registers become the reset signals ... requirement to go active at the end of configuration, ...
    (comp.lang.vhdl)
  • Re: Event Driven State Machine
    ... interior clock, and is completely driven by a SCLK input that is only ... And passing signals to the procedure as arguments will work nicely... ... default assignments and wait for reset again? ... If reset event Then ...
    (comp.lang.vhdl)
  • Re: Problem with simple VHDL piece of code
    ... to use an explicit reset of some kind. ... behind "counter" by one clock cycle. ... comparator is now trivial, and involves no arithmetic. ... A smart synthesizer might do a reachability analysis on the counter, ...
    (comp.lang.vhdl)
  • Question re booting a 68000 CPU
    ... What are the essential signals required by a 68000 CPU in order to get ... Obviously Clock and Reset - but what else MUST be functional? ... having valid Clock and Reset signals, are doing absolutely bugger all, ...
    (sci.electronics.misc)
  • Re: if and and vs if and,and
    ... signal reset: std_logic; ... elsif rising_edge (clock) then ... signals event, in sensitivity list. ...
    (comp.lang.vhdl)