noob question on loops

K

Karol Hennessy

I'm currently trying to work through some examples in one of Pong Chu's books.  There's one thing I'm not quite clear on.  In many of his exampleshe uses lots of if .. else statements, but hardly ever for loops.  In some of the questions, you're asked to extend some example he has given, e.g.going from say 4bit input to 12bit or something like that.

For this kind of example, it seems natural to me to use some sort of loop for each of the 12bits.  Is this poor practice?

One example he gives is a priority encoder, where you output the highest bit that is set to 1.  If we have 4 bit input and 3 bit output, we would have

in      out 
"1XXX" "100" (4)
"01XX" "011" (3)
"001X" "010" (2)
"0001" "001" (1)
"0000" "000" (0)

If we had some 32bit input std_logic_vector, would we really have to explicitly code each case or is there some sort of looping we can use?  What isthe preferred method to deal with long std_logic_vectors?
 
G

GaborSzakacs

Karol said:
I'm currently trying to work through some examples in one of Pong Chu's books. There's one thing I'm not quite clear on. In many of his examples he uses lots of if .. else statements, but hardly ever for loops. In some of the questions, you're asked to extend some example he has given, e.g. going from say 4bit input to 12bit or something like that.

For this kind of example, it seems natural to me to use some sort of loop for each of the 12bits. Is this poor practice?

One example he gives is a priority encoder, where you output the highest bit that is set to 1. If we have 4 bit input and 3 bit output, we would have

in out
"1XXX" "100" (4)
"01XX" "011" (3)
"001X" "010" (2)
"0001" "001" (1)
"0000" "000" (0)

If we had some 32bit input std_logic_vector, would we really have to explicitly code each case or is there some sort of looping we can use? What is the preferred method to deal with long std_logic_vectors?

Loops are a perfectly valid way to implement a priority encoder. Often
textbooks are very behind the curve in synthesis technology, and it
wasn't that long ago that many synthesis tools had poor if any
support for loops. Also it is generally not a good idea for beginners
to start thinking in terms of loops until they have an understanding
of the potentially large hardware that a loop creates when it gets
unrolled.

I'm most familiar with Xilinx tools, where there are some strict
restriction on loops, especially that the number of iterations
must be a constant at synthesis time. So in the case of a 32-bit
priority encode, your loop for simulation would probably work
best if it is coded to exit as soon as the first '1' bit is
found. But for synthesis, at least for XST, you'd code it with
a variable to remember that the first one has already been found and
an if statement to prevent further assignments on the remining
loop iterations.

-- Gabor
 
R

rickman

Loops are a perfectly valid way to implement a priority encoder. Often
textbooks are very behind the curve in synthesis technology, and it
wasn't that long ago that many synthesis tools had poor if any
support for loops. Also it is generally not a good idea for beginners
to start thinking in terms of loops until they have an understanding
of the potentially large hardware that a loop creates when it gets
unrolled.

I'm most familiar with Xilinx tools, where there are some strict
restriction on loops, especially that the number of iterations
must be a constant at synthesis time. So in the case of a 32-bit
priority encode, your loop for simulation would probably work
best if it is coded to exit as soon as the first '1' bit is
found. But for synthesis, at least for XST, you'd code it with
a variable to remember that the first one has already been found and
an if statement to prevent further assignments on the remining
loop iterations.

I've been coding in VHDL for some 15+ years and I can't remember using
loops for synthesized code once. But I think a priority encoder would
be a perfect use of a loop. I would loop from the lowest priority bit
to the highest priority bit and overwrite the variable with the
corresponding bit number each time it is a one. At the end of the loop
the variable is set to the right value and can be assigned to a signal.
BTW, do you plan to have a separate signal to indicate the presence of
a 1 bit in the word or will you use a zero code for no bits set and use
a 1 based count for the msb bit position requiring a 6 bit priority word?

I would code this unit separately and test it in synthesis to see what
is produced. It should produce the priority chain of gates or more
likely optimize it to something not so easily recognizable. But it
would be interesting to see if it is reasonably efficient. At 32 bits a
priority encoder can be pretty messy.

Rick
 
A

Andy

On 1/21/2013 1:51 PM, GaborSzakacs wrote: > Karol Hennessy wrote: >> I'm currently trying to work through some examples in one of Pong >> Chu's books. There's one thing I'm not quite clear on. In many of his >> examples he uses lots of if .. else statements, but hardly ever for >> loops. In some of the questions, you're asked to extend some example >> he has given, e.g. going from say 4bit input to 12bit or something >> like that. >> >> For this kind of example, it seems natural to me to use some sort of >> loop for each of the 12bits. Is this poor practice? >> >> One example he gives is a priority encoder, where you output the >> highest bit that is set to 1. If we have 4 bit input and 3 bit output, >> we would have >> >> in out "1XXX" "100" (4) >> "01XX" "011" (3) >> "001X" "010" (2) >> "0001" "001" (1) >> "0000" "000" (0) >> >> If we had some 32bit input std_logic_vector, would we really have to >> explicitly code each case or is there some sort of loopingwe can use? >> What is the preferred method to deal with long std_logic_vectors? > > Loops are a perfectly valid way to implement a priority encoder.Often > textbooks are very behind the curve in synthesis technology, and it > wasn't that long ago that many synthesis tools had poor if any > support for loops. Also it is generally not a good idea for beginners > to start thinking in terms of loops until they have an understanding > of the potentially large hardware that a loop creates when it gets > unrolled. > > I'm most familiar with Xilinx tools, where there are some strict > restriction on loops, especially that the number of iterations > must be a constant at synthesis time. So in the case of a 32-bit > priority encode, your loop for simulation would probably work > best if it is coded to exit as soon as thefirst '1' bit is > found. But for synthesis, at least for XST, you'd code it with > a variable to remember that the first one has already been found and > an if statement to prevent further assignments on the remining > loopiterations. I've been coding in VHDL for some 15+ years and I can't remember using loops for synthesized code once. But I think a priority encoder would be a perfect use of a loop. I would loop from the lowest priority bit to the highest priority bit and overwrite the variable with the corresponding bit number each time it is a one. At the end of the loop the variable is set to the right value and can be assigned to a signal. BTW, do you plan tohave a separate signal to indicate the presence of a 1 bit in the word or will you use a zero code for no bits set and use a 1 based count for the msb bit position requiring a 6 bit priority word? I would code this unit separately and test it in synthesis to see what is produced. It should produce the priority chain of gates or more likely optimize it to something not so easily recognizable. But it would be interesting to see if it is reasonablyefficient. At 32 bits a priority encoder can be pretty messy. Rick

If you are not comfortable or familiar with using loops in synthesis, I stronly agree that caution is necessary.

IMHO, most university courseware for HDL based design does a miserable job of covering basic SW techniques that are fully applicable to HW design. So unless one snoops around on their own, purchases the right book, or gets advanced training, they are unlikely to understand or use these techniques. That is not to say that you can't design reliable HW without these techniques, but it is much harder to develop maintainable, reliable designs without them.

I've been designing programmable HW with VHDL for going on 21 years now, and for most of those I have used loops in synthesis with excellent results. The key is understanding how the loop's behavior tranlates into hardware, and whatever restrictions synthesis tools have on their use.

In virtually all synthesis tools, loops are supported, as long as they don't contain a wait statement. Thus they iterate in zero time/deltas. Among other things, this means that a signal assigned in one iteration will not be updated for subsequent iterations. If you need something like that (e.g. parity), use a variable to hold the value, so the updated value is available in later iterations.

Simply stated, synthesis unrolls loops, and therefore requires a static (known at synthesis time) limit for the loop so that the correct number of iterations to unroll is known. You can use a conditional exit statement with adynamic value to terminate the loop (this unrolls to a long if-elsif-elsif.... statement).

The resulting hardware is identical whether you used a loop or wrote out N copies of the loop's statements manually.

Just like a SW, loops are critical structures for handling lots of situations in elegant, understandable and maintainable code. In VHDL you can invokethe 'range attribute of an array in the for loop statement to automatically iterate over each item in the array. You can also use 'reverse_range to iterate backwards. Using these tricks not only makes the code more reliable,it allows you to tell (in a verifiable, executable statement, not a comment) the user WHAT your are iterating on (kinda like a foreach).

Andy
 
V

valtih1978

a wait statement

Wait. My teacher taught me that "a" means "one" in English. And, this is
what all synthesizers want in VHDL -- one and only one wait.
 
R

rickman

hat is the preferred method to deal with long std_logic_vectors?> > Loops are a perfectly valid way to implement a priority encoder. Often> textbooks are very behind the curve in synthesis technology, and it> wasn't that long ago that many synthesis tools had poor if any> support for loops. Also it is generally not a good idea for beginners> to start thinking in terms of loops until they have an understanding> of the potentially large hardware that a loop creates when it gets> unrolled.> > I'm most familiar with Xilinx tools, where there are some strict> restriction on loops, especially that the number of iterations> must be a constant at synthesis time. So in the case of a 32-bit> priority encode, your loop for simulation would probably work> best if it is coded to exit as soon as the first '1' bit is> found. But for synthesis, at least for XST, you'd code it with> a variable to remember that the first one has already been found and> an if statement to prevent furth
er assignments on the remining> loop iterations. I've been coding in VHDL for some 15+ years and I can't remember using loops for synthesized code once. But I think a priority encoder would be a perfect use of a loop. I would loop from the lowest priority bit to the highest priority bit and overwrite the variable with the corresponding bit number each time it is a one. At the end of the loop the variable is set to the right value and can be assigned to a signal. BTW, do you plan to have a separate signal to indicate the presence of a 1 bit in the word or will you use a zero code for no bits set and use a 1 based count for the msb bit position requiring a 6 bit priority word? I would code this unit separately and test it in synthesis to see what is produced. It should produce the priority chain of gates or more likely optimize it to something not so easily recognizable. But it would be interesting to see if it is reasonably efficient. At 32 bits a priority encoder can be pretty messy
.. Rick
If you are not comfortable or familiar with using loops in synthesis, I stronly agree that caution is necessary.

IMHO, most university courseware for HDL based design does a miserable job of covering basic SW techniques that are fully applicable to HW design. So unless one snoops around on their own, purchases the right book, or gets advanced training, they are unlikely to understand or use these techniques. That is not to say that you can't design reliable HW without these techniques, but it is much harder to develop maintainable, reliable designs without them. ....snip...

Andy

I never said I was "not comfortable" or familiar with using loops in
synthesis. I said I hadn't used one that I can recall, meaning I've
found little need. I don't recall ever coding a priority encoder which
is one function that can be easily with a loop. Otherwise I can't think
of any functions that are easier or better described with a loop.

Can you give some common examples of loops in synthesis?

Rick
 
H

HT-Lab

I don't think that's completely true.

I seem to remember that Leonardo Spectrum could understand an implicit
state machine coding style which had multiple wait statements in a
single process.

But I haven't tried that out recently with modern tools.

Mentor's Precision can and I assume Synplify as well,

process
begin
wait until clk'event AND clk='1';
output_signal <= 0;
while (input_signal < 6) loop
wait until clk'event AND clk='1';
output_signal <= output_signal+1;
end loop;
end process;

Not sure about XST/Vivado/QNS....

Regards,
Hans
www.ht-lab.com


I always tell
 
G

GaborSzakacs

Alan said:
I don't think that's completely true.

I seem to remember that Leonardo Spectrum could understand an implicit
state machine coding style which had multiple wait statements in a
single process.

But I haven't tried that out recently with modern tools. I always tell
people on training courses to only use one wait in a synthesisable
process :)

regards
Alan
Even if a process has more than one wait, it cannot synthesize
with any tool I'm aware of unless all waits are on the same
event, for example rising_edge(clk). And many synthesizers
are more restrictive than that.

-- Gabor
 
T

Tricky

hat is the preferred method to deal with long std_logic_vectors?> > Loops are a perfectly valid way to implement a priority encoder. Often> textbooks are very behind the curve in synthesis technology, and it> wasn't that long ago that many synthesis tools had poor if any> support for loops. Also it is generally not a good idea for beginners> to start thinking in terms of loops until they have an understanding> of the potentially large hardware that a loop creates when it gets> unrolled.> > I'm most familiar with Xilinx tools, where there are some strict> restriction on loops, especially that the number of iterations> must be a constant at synthesis time.. So in the case of a 32-bit> priority encode, your loop for simulation would probably work> best if it is coded to exit as soon as the first '1' bit is> found. But for synthesis, at least for XST, you'd code it with> a variable to remember that the first one has already been found and> an if statement to prevent furth

er assignments on the remining> loop iterations. I've been coding in VHDL for some 15+ years and I can't remember using loops for synthesized code once. But I think a priority encoder would be a perfect use of a loop. I would loop from the lowest priority bit to the highest priority bit and overwrite the variable with the corresponding bit number each time it is a one. At the end of the loop the variable is set to the right value and can be assigned to a signal. BTW, do you plan to have a separate signal to indicate the presence of a 1 bit in the word or will you use a zero code for no bitsset and use a 1 based count for the msb bit position requiring a 6 bit priority word? I would code this unit separately and test it in synthesis to see what is produced. It should produce the priority chain of gates or more likely optimize it to something not so easily recognizable. But it would beinteresting to see if it is reasonably efficient. At 32 bits a priority encoder can be pretty messy

. Rick





I never said I was "not comfortable" or familiar with using loops in

synthesis. I said I hadn't used one that I can recall, meaning I've

found little need. I don't recall ever coding a priority encoder which

is one function that can be easily with a loop. Otherwise I can't think

of any functions that are easier or better described with a loop.



Can you give some common examples of loops in synthesis?



Rick

Mult-adder trees where the input sizes are a generic would be an easy one for loops. But you could move them to generate loops (But IMO, the loops inside a process would be tidier because you dont need the extra signals for the reigsters).

And being pedantic, all of the numeric_std arithmatic, and the reduction oporators in std_logic_misc all use for loops.
 
A

Andy

On 1/22/2013 11:56 AM, Andy wrote: > On Monday, January 21, 2013 1:57:43 PM UTC-6, rickman wrote: >> On 1/21/2013 1:51 PM, GaborSzakacs wrote:> Karol Hennessy wrote:>> I'm currently trying to work through some examples in one of Pong>> Chu's books. There's one thing I'm not quite clear on. In manyof his>> examples he uses lots of if .. else statements, but hardly ever for>> loops. In some of the questions, you're asked to extend some example>>he has given, e.g. going from say 4bit input to 12bit or something>> like that.>> >> For this kind of example, it seems natural to me to use some sort of>> loop for each of the 12bits. Is this poor practice?>> >> One examplehe gives is a priority encoder, where you output the>> highest bit that isset to 1. If we have 4 bit input and 3 bit output,>> we would have>> >> inout "1XXX" "100" (4)>> "01XX" "011" (3)>> "001X" "010" (2)>> "0001" "001" (1)>> "0000" "000" (0)>> >> If we had some 32bit input std_logic_vector, would we really have to>> explicitly code each case or is there some sort of looping we can use?>> W hat is the preferred method to deal with long std_logic_vectors?> > Loops are a perfectly valid way to implement a priority encoder. Often> textbooks are very behind the curve in synthesis technology, and it> wasn't that long ago that many synthesis tools had poor if any> support for loops. Also it is generally not a good idea for beginners> to start thinking in terms of loops until they have an understanding> of the potentially large hardware that a loop creates when it gets> unrolled.> > I'm most familiar with Xilinx tools, where there are some strict> restriction on loops, especially that the number of iterations> must be a constant at synthesis time. So in the case of a 32-bit> priority encode, your loop for simulation would probably work> best if it is coded to exit as soon as the first '1' bit is> found. But for synthesis, at least for XST, you'd code it with> a variable to remember that the first one has already been found and> anif statement to prevent furth er assignments on the remining> loop iterations. I've been coding in VHDL for some 15+ years and I can't remember usingloops for synthesized code once. But I think a priority encoder would be aperfect use of a loop. I would loop from the lowest priority bit to the highest priority bit and overwrite the variable with the corresponding bit number each time it is a one. At the end of the loop the variable is set to the right value and can be assigned to a signal. BTW, do you plan to have a separate signal to indicate the presence of a 1 bit in the word or will youuse a zero code for no bits set and use a 1 based count for the msb bit position requiring a 6 bit priority word? I would code this unit separately and test it in synthesis to see what is produced. It should produce the priority chain of gates or more likely optimize it to something not so easily recognizable. But it would be interesting to see if it is reasonably efficient. At 32 bits a priority encoder can be pretty messy . Rick > > If you arenot comfortable or familiar with using loops in synthesis, I stronly agreethat caution is necessary. > > IMHO, most university courseware for HDL based design does a miserable job of covering basic SW techniques that are fully applicable to HW design. So unless one snoops around on their own, purchases the right book, or gets advanced training, they are unlikely to understand or use these techniques. That is not to say that you can't design reliable HW without these techniques, but it is much harder to develop maintainable, reliable designs without them. ...snip... > > Andy I never said I was "not comfortable" or familiar with using loops in synthesis. I said I hadn't used one that I can recall, meaning I've found little need. I don't recall ever coding a priority encoder which is one function that can be easilywith a loop. Otherwise I can't think of any functions that are easier or better described with a loop. Can you give some common examples of loops in synthesis? Rick

Sorry, I only meant to say that those who have not used loops, tend not to see where they might be used to advantage. If you don't have a hammer, you probably don't go around looking for nails to sink. That's all.

Parity was a very common application of a loop, but with the unary XOR operator, this is no longer necessary.

Parameterized CRC encoding.

Parameterized-width Hamming encode/decode.

One of my most common use cases is the following:

If I have a 3 bit sub-address A with which to index a 6-register array Q, Ican't just use "Q(to_integer(A)) := D", since A may be outside of Q'range.

variable a : unsigned(2 downto 0);
variable q : unsigned(5 downto 0);

for i in reg'range loop
if a = i then
q(i) := d;
exit; -- speed up simulation, no effect on HW
end if;
end loop;

If A is an integer, you might be able to code it as follows, but q'range must be locally static:

variable a : natural range 0 to 7;
variable q : unsigned(5 downto 0);

case a is
when q'range =>
q(a) := d;
when others =>
null;
end case;

Andy
 
R

Rob Gaddi

Can you give some common examples of loops in synthesis?

Rick

Sure, there's a function I've used from time to time when I'm going to
have a lot of fixed modulo up-counters in a design; a trick that I stole
from the TTL on boards days.

pure function counter_eq(x : in unsigned; tgt : in natural)
return boolean is

variable target : unsigned(x'range);
begin
target := TO_UNSIGNED(tgt, target'length);
for i in target'range loop
if (target(i) = '1') and (x(i) /= '1') then
return false;
end if;
end loop;
return true;
end function counter_eq;

The idea is that, given a synchronous up-counter x with a constant tgt,
the time at which (x = tgt) is the same as the first time that all the
bits that are 1 in tgt are also 1 in x. This means that you can ignore
the zero bits; they're not interesting. They'd come into play if you
kept counting past tgt; you'd start getting lots of false equality
hits. But you're not going to do that, you're going to reset at tgt;
so you're fine.

If you're counting, especially to a large number with few bits set,
such as 0xA000, ignoring the 0 bits can save you a couple LUTs. But
more importantly, it reduces the combinational function to where it can
fit in only 1 level of logic, rather than having to chain LUTs
together. It's saved my bacon a couple of times when I've been having
my face ground into the timing wall.
 
R

rickman

Mult-adder trees where the input sizes are a generic would be an easy one for loops. But you could move them to generate loops (But IMO, the loops inside a process would be tidier because you dont need the extra signals for the reigsters).

And being pedantic, all of the numeric_std arithmatic, and the reduction oporators in std_logic_misc all use for loops.

Ok, but they have been written, I don't need to write them again.

Have you used loops for any of these things? I think I mistook a
limitation that someone said and have mis-classified some of the code
that might be useful as not allowed. You can't use a wait (or I assume
a rising edge) statement in a loop. But that doesn't mean you can't
have the loop in the context of a rising edge if and so the loop can
infer multiple registers. I had my goggles on sideways.

Rick
 
R

rickman

ould we really have to>> explicitly code each case or is there some sort of looping we can use?>> W hat is the preferred method to deal with long std_logic_vectors?> > Loops are a perfectly valid way to implement a priority encoder. Often> textbooks are very behind the curve in synthesis technology, and it> wasn't that long ago that many synthesis tools had poor if any> support for loops. Also it is generally not a good idea for beginners> to start thinking in terms of loops until they have an understanding> of the potentially large hardware that a loop creates when it gets> unrolled.> > I'm most familiar with Xilinx tools, where there are some strict> restriction on loops, especially that the number of iterations> must be a constant at synthesis time. So in the case of a 32-bit> priority encode, your loop for simulation would probably work> best if it is coded to exit as soon as the first '1' bit is> found. But for synthesis, at least for XST, you'd code it with> a
variable to remember that the first one has already been found and> an if statement to prevent furth er assignments on the remining> loop iterations. I've been coding in VHDL for some 15+ years and I can't remember using loops for synthesized code once. But I think a priority encoder would be a perfect use of a loop. I would loop from the lowest priority bit to the highest priority bit and overwrite the variable with the corresponding bit number each time it is a one. At the end of the loop the variable is set to the right value and can be assigned to a signal. BTW, do you plan to have a separate signal to indicate the presence of a 1 bit in the word or will you use a zero code for no bits set and use a 1 based count for the msb bit position requiring a 6 bit priority word? I would code this unit separately and test it in synthesis to see what is produced. It should produce the priority chain of gates or more likely optimize it to something not so easily recognizable. But it would
be interesting to see if it is reasonably efficient. At 32 bits a priority encoder can be pretty messy . Rick> > If you are not comfortable or familiar with using loops in synthesis, I stronly agree that caution is necessary.> > IMHO, most university courseware for HDL based design does a miserable job of covering basic SW techniques that are fully applicable to HW design. So unless one snoops around on their own, purchases the right book, or gets advanced training, they are unlikely to understand or use these techniques. That is not to say that you can't design reliable HW without these techniques, but it is much harder to develop maintainable, reliable designs without them. ...snip...> > Andy I never said I was "not comfortable" or familiar with using loops in synthesis. I said I hadn't used one that I can recall, meaning I've found little need. I don't recall ever coding a priority encoder which is one function that can be easily with a loop. Otherwise I can't think of any
functions that are easier or better described with a loop. Can you give some common examples of loops in synthesis? Rick
Sorry, I only meant to say that those who have not used loops, tend not to see where they might be used to advantage. If you don't have a hammer, you probably don't go around looking for nails to sink. That's all.

Parity was a very common application of a loop, but with the unary XOR operator, this is no longer necessary.

Parameterized CRC encoding.

Parameterized-width Hamming encode/decode.

Believe it or not, I just haven't done any of these things that I can
recall.

One of my most common use cases is the following:

If I have a 3 bit sub-address A with which to index a 6-register array Q, I can't just use "Q(to_integer(A)) := D", since A may be outside of Q'range.

variable a : unsigned(2 downto 0);
variable q : unsigned(5 downto 0);

for i in reg'range loop
if a = i then
q(i) := d;
exit; -- speed up simulation, no effect on HW
end if;
end loop;

No need for a loop here.

variable a : unsigned(2 downto 0);
variable q : unsigned(5 downto 0);
variable i : integer range 0 to 5;

if (a <= reg'high) then
i := to_integer(a);
q(i) <= d;
end if;

Isn't this simpler and likely faster?

If A is an integer, you might be able to code it as follows, but q'range must be locally static:

variable a : natural range 0 to 7;
variable q : unsigned(5 downto 0);

case a is
when q'range =>
q(a) := d;
when others =>
null;
end case;

Not trying to be contrary, but this is just not a good thing. I would
make the range of 'a' match the range of the array 'q'. In the case of
the vector 'a', I can see where you have a problem, but what is the need
for declaring the integer range to be larger than the size of the
register array?

Rick
 
A

Andy

Rick,

In the past, I found using the range check conditional added hardware and was slower. Maybe the tools are smarter now.

As far as faster, in simulator run time or HW performance? You can't beat the loop in HW; it spits out one decoder for each register (try unrolling the loop by hand). The simulator does run the loop slower.

If I am the one generating the subaddress, then yes, I can constrain it accordingly. But I don't have control over the subaddress when it is an external input that could be any N-bit value. If it is outside of q'range, I just ignore it (do nothing).

Andy
 
R

rickman

Rick,

In the past, I found using the range check conditional added hardware and was slower. Maybe the tools are smarter now.

I will have to try this an see. I can't imagine it would add any
hardware. The address decode function implicit in the array should
preempt any additional logic. Enabling the register when the address is
N should not need any additional logic to disable the register when the
address is M.

As far as faster, in simulator run time or HW performance? You can't beat the loop in HW; it spits out one decoder for each register (try unrolling the loop by hand). The simulator does run the loop slower.

I meant simulator. The hardware generated should be the same as it only
requires the input of the three address bits.

If I am the one generating the subaddress, then yes, I can constrain it accordingly. But I don't have control over the subaddress when it is an external input that could be any N-bit value. If it is outside of q'range, I just ignore it (do nothing).

This also shows limitations in my knowledge of VHDL. This language has
so many restrictions and I use it so intermittently that I can't
remember details from project to project.

I'll let you know what I find with the tools I'm currently using.
That's not saying much. I'm working with the iCE40 devices from Lattice
(formerly SiBlue) and the tools seem pretty crude. I tried an enabled
up/down counter the other day and it was using two LUTs per bit and not
because of any hardware issues. I contacted support and they gave me
some rather more complex code that was able to invoke the enable. We'll
see...

Rick
 
R

rickman

Sure, there's a function I've used from time to time when I'm going to
have a lot of fixed modulo up-counters in a design; a trick that I stole
from the TTL on boards days.

pure function counter_eq(x : in unsigned; tgt : in natural)
return boolean is

variable target : unsigned(x'range);
begin
target := TO_UNSIGNED(tgt, target'length);
for i in target'range loop
if (target(i) = '1') and (x(i) /= '1') then
return false;
end if;
end loop;
return true;
end function counter_eq;

The idea is that, given a synchronous up-counter x with a constant tgt,
the time at which (x = tgt) is the same as the first time that all the
bits that are 1 in tgt are also 1 in x. This means that you can ignore
the zero bits; they're not interesting. They'd come into play if you
kept counting past tgt; you'd start getting lots of false equality
hits. But you're not going to do that, you're going to reset at tgt;
so you're fine.

If you're counting, especially to a large number with few bits set,
such as 0xA000, ignoring the 0 bits can save you a couple LUTs. But
more importantly, it reduces the combinational function to where it can
fit in only 1 level of logic, rather than having to chain LUTs
together. It's saved my bacon a couple of times when I've been having
my face ground into the timing wall.

That is an interesting trick. I don't think I've ever had the need for
it as I typically use down counters and terminate using the carry chain.
One level of logic may be faster depending on the length of the
counter, in fact, if it really is only one level of logic, I am sure
that would be faster as the carry chain has time costs getting out of
the chain and into the general routing. But I'm seldom pressed for
speed on a counter and the carry is just so easy...

Rick
 

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,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top