Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > vhdl questions from a verilog person

Reply
Thread Tools

vhdl questions from a verilog person

 
 
Mark Brehob
Guest
Posts: n/a
 
      01-28-2009
Hello all,
I'm a teacher who has been teaching students Verilog for a while, but
for various reasons I've had to jump to VHDL for a certain course.
I've been writing a fair bit of simple VHDL stuff (basic DSP
algorithms), and found it both powerful and frustrating. Mostly I'm
trying to figure out if there are better ways to do things and why
VHDL and/or VHDL coders do certain things.

As a note most of my verilog experience is doing synthesizable ASIC
(with some FPGA) while my VHDL stuff is all FPGA based.

#1 Why no process(*) statement similar to always@*?

The vast majority of all process statements are either modeling
combinational logic or something that changes only on clock/reset.
Why doesn't VHDL have a process(*) kind of statement as verilog does
saying "this is combinational logic, update if any of the inputs
change". Having to get the process statement right is painful to
student (add a variable and forget to update the process line) and
further, Xilinx software (at least) just adds things to the process
list anyways with just a warning.


#2 How do I add two values both of which are arbitrary in size?

So say I have one STD_LOGIC_VECTOR that is X bits and one that is Y
bits. Is there a clean way to add them (into something of Z bits for
sake of argument)? I find myself casting to an integer (and back) to
get stuff to work but that's neither pretty nor probably a good
idea.


#3 Is there a good way to index an array with a STD_LOGIC_VECTOR?

Again, I found myself casting back and forth. I suspect here there is
a right way to do this and I'm just missing it.


#4 What's up with all the different ways to check for a rising edge of
a clock?

The code base I inherited uses rising_edge, but that seems to be
fairly uncommon if code I find on the net is any indicator. I think
I've seen three other ways to do it. (Old value was 0 new is one,
current value is 1 and there was a change event, and one other.) Is
there a good reason everyone doesn't just use rising_edge? Is there
something I'm missing?



I had a bunch of other questions, but of course I've forgotten (did my
coding over the weekend and I guess 48 hours ago is enough time to
forget). I'm mostly enjoying it, but as you might expect, it's
bringing back Ada nightmares. At the current time I feel like I'm
jumping through hoops to get around the strict type checking (just
like I recall doing years ago with Ada). C/Verilog people should not
have to deal with strict type checking .

Humm, I guess I'd like thoughts on my coding style, but the students
are finishing "filling in the blanks" on my code, so that will have to
wait until next week.

Thanks in advance,
Mark
 
Reply With Quote
 
 
 
 
Andreas Ehliar
Guest
Posts: n/a
 
      01-28-2009
On 2009-01-28, Mark Brehob <(E-Mail Removed)> wrote:
> As a note most of my verilog experience is doing synthesizable ASIC
> (with some FPGA) while my VHDL stuff is all FPGA based.
>
> #1 Why no process(*) statement similar to always@*?


Hi,

you have already gotten some nice answers but I thought I'd chip in with
a few additional notes:

* It is much easier to write combinational logic outside of a process
in VHDL. When I was going from VHDL to Verilog I was very frustrated that
the only way to create a condition outside an always block was to use
the ? operation. In VHDL you have the "with foo select ..." construct
which is very nice if you need to create a multiplexer for example.

* I believe that vhdl-mode for Emacs is able to automatically update
a process sensitivity list for you but I haven't tried that myself.


And some encouragement: Think of how nice it will be to know that the
students' code will not contain any blocking/non-blocking races.

/Andreas
 
Reply With Quote
 
 
 
 
KJ
Guest
Posts: n/a
 
      01-28-2009

"Mark Brehob" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hello all,
>
> #1 Why no process(*) statement similar to always@*?
>


To frustrate people mostly.

> The vast majority of all process statements are either modeling
> combinational logic or something that changes only on clock/reset.
> Why doesn't VHDL have a process(*) kind of statement as verilog does
> saying "this is combinational logic, update if any of the inputs
> change".


I think that is part of VHDL-2008...whenever the vendors get around to
implementing it in the tools.

> Having to get the process statement right is painful to
> student (add a variable and forget to update the process line)


That's one reason why this newsgroup generally does not recommend using
combinatorial processes. Use only clocked processes (with or without
variables as needs and whims dictate) and concurrent statements. Use
functions and procedures.

Another reason is that combinatorial processes are 'bad' is that one needs
to make sure that every signal gets assigned through every path. Generally
this gets handled by applying the 'default' value at the start of the
process. This is just more typing, effort, and trouble then using clocked
processes and concurrent statements.

> and
> further, Xilinx software (at least) just adds things to the process
> list anyways with just a warning.
>


And there is the other reason for avoiding such beasts...having simulation
be different than synthesis because you missed the 'warning'.

Try to avoid teaching use of these things, you'll be helping them in the
long run by showing how to avoid three common design errors that require
debug time to root out the cause.

>
> #2 How do I add two values both of which are arbitrary in size?
>
> So say I have one STD_LOGIC_VECTOR that is X bits and one that is Y
> bits. Is there a clean way to add them (into something of Z bits for
> sake of argument)? I find myself casting to an integer (and back) to
> get stuff to work but that's neither pretty nor probably a good
> idea.
>


Not every signal needs to be defined as std_logic_vector though. If
something is inherently an integer, than define it that way you'll avoid the
casting.

If you do need vectors, then look as ieee.numeric_std for your arithmetic,
it will do the things you've mentioned. That package defines two vector
types called 'signed' and 'unsigned' that apply a specific numeric
interpretation to the vector, as opposed to std_logic_vector which is simply
a collection of bits. Again, to avoid a lot of type casting, it is usually
best to define things using the correct type instead of always using
std_logic_vector and casting. One place where you should stick with
std_logic_vector though is at the top level entity ports.

>
> #3 Is there a good way to index an array with a STD_LOGIC_VECTOR?
>


Yes...use an integer instead, which is what you're doing with the casting
X(to_integer(unsigned(my_slv)) <= '1';

> Again, I found myself casting back and forth. I suspect here there is
> a right way to do this and I'm just missing it.
>


Casting is the only way to do it...if you start with the mindset that
everything must be std_logic_vector. Use of other data types that are more
appropriate to start with is the way to avoid the ugliness of excessive type
casts.

>
> #4 What's up with all the different ways to check for a rising edge of
> a clock?
>


I only use "if rising_edge(clock) then..." or "wait until
rising_edge(clock);" It's self documenting. I have no idea why people use
less clear ways of expressing something so simple, but you're right they
certainly do.

> The code base I inherited uses rising_edge, but that seems to be
> fairly uncommon if code I find on the net is any indicator.


Not everything on the net is worth spit though...

> I think
> I've seen three other ways to do it. (Old value was 0 new is one,
> current value is 1 and there was a change event, and one other.) Is
> there a good reason everyone doesn't just use rising_edge? Is there
> something I'm missing?
>


I think the others are the ones missing something, not you.

Kevin Jennings


 
Reply With Quote
 
Andreas Ehliar
Guest
Posts: n/a
 
      01-28-2009
On 2009-01-28, Mark Brehob <(E-Mail Removed)> wrote:
> Actually, good coding style in Verilog completely eliminates that
> problem. In my other class, the students build a synthisizable out-of-
> order processor starting with an in-order processor. We've found that
> blocking/non-blocking problems just don't occur if you follow simple
> rules. We teach those rules as "required" and the problem go away.
> See http://www.eecs.umich.edu/courses/ee...guidelines.pdf
> for a short summary.


Well, we teach more or less the same rules as well, but there is always
at least one group per year who manages to come up with some nice and
interesting blocking/non-blocking race condition

The course you are talking about sounds very interesting by the way,
I wish I could have attended such a course as an undergraduate student.
Do you know roughly how much time students spend doing the projects in
this course? Do they have to care about the efficiency of their
RTL code or do they only have to get it synthesizable?

/Andreas
 
Reply With Quote
 
Mark Brehob
Guest
Posts: n/a
 
      01-28-2009
On Jan 27, 9:00*pm, Andreas Ehliar <(E-Mail Removed)> wrote:
> On 2009-01-28, Mark Brehob <(E-Mail Removed)> wrote:
>


>
> And some encouragement: Think of how nice it will be to know that the
> students' code will not contain any blocking/non-blocking races.
>
> /Andreas


Actually, good coding style in Verilog completely eliminates that
problem. In my other class, the students build a synthisizable out-of-
order processor starting with an in-order processor. We've found that
blocking/non-blocking problems just don't occur if you follow simple
rules. We teach those rules as "required" and the problem go away.
See http://www.eecs.umich.edu/courses/ee...guidelines.pdf
for a short summary.

Verilog has lots of problems (generate statement can really be a pain,
multi-port memories can be a huge challenge, etc.), but blocking/non-
blocking problems don't pop up after the first 2 weeks of the class.
Heck, type-checking problems are rare (but certainly happen).
Mark
 
Reply With Quote
 
Mark Brehob
Guest
Posts: n/a
 
      01-28-2009
On Jan 27, 8:53*pm, Jim Lewis <(E-Mail Removed)> wrote:
> Mark> #1 Why no process(*) statement similar to always@*?
>
> Process(all) is in the Accellera VHDL 3.0 2006 trial standard
> and in IEEE 1076-2008.
>
> To everyone out there, make sure your vendors know this is
> important to you as they have had 2.5 years already to work on it.
> I would recommend submitting it as a bug report.
>
> > #2 How do I add two values both of which are arbitrary in size?

>
> > So say I have one STD_LOGIC_VECTOR that is X bits and one that is Y
> > bits. *Is there a clean way to add them (into something of Z bits for
> > sake of argument)? *I find myself casting to an integer (and back) to
> > get stuff to work but that's neither pretty nor probably a good
> > idea.

>
> Std_logic_vector is not a math type. *Types signed and unsigned are.
> See the paper, VHDL Math Tricks of the Trade from the website:http://www.synthworks.com/papers/index.htm
>
> > #3 Is there a good way to index an array with a STD_LOGIC_VECTOR?

>
> > Again, I found myself casting back and forth. *I suspect here there is
> > a right way to do this and I'm just missing it.

>
> You need to convert it to integer. *The conversion is as follows,
> where a_slv is the value you need to convert. *See the referenced
> paper for details.
>
> * *to_integer(unsigned(a_slv))
>
> > #4 What's up with all the different ways to check for a rising edge of
> > a clock?

>
> Rising_edge is the newer (from synthesis tool support) and more readable
> way to do this.
>
> When coding a simple register:
>
> ARegProc : process(nReset, Clk)
> begin
> * *if nReset = '0' then
> * * *AReg <= '0' ;
> * *elsif rising_edge(Clk) then
> * * *AReg <= A ;
> * *end if ;
> end process ;
>
> WRT portable coding styles, I recommend either rising_edge or the following
> (note that I prefer rising_edge):
> * *elsif clk='1' and clk'event then
> * *elsif clk'event and clk='1' then
>
> These are real old and may or may not be portable (work in all synthesis tools):
> * *elsif clk='1' and not clk'stable then
> * *elsif not clk'stable and clk='1' then
>
> This one was supported by a particular tool (which is now gone) and
> I doubt it is portable (which may be confusing as it is very similar
> to the rising_edge procedure):
> * *elsif clk='1' and clk'event and clk ='0' then
> * *... and its variations
>
> > I had a bunch of other questions, but of course I've forgotten (did my
> > coding over the weekend and I guess 48 hours ago is enough time to
> > forget). *I'm mostly enjoying it, but as you might expect, it's
> > bringing back Ada nightmares. *At the current time I feel like I'm
> > jumping through hoops to get around the strict type checking (just
> > like I recall doing years ago with Ada). *C/Verilog people should not
> > have to deal with strict type checking .

>
> Yes, but the DVCon paper that I saw that used a lint tool to apply
> VHDL type checking rules to Verilog (to simplify code conversion)
> indicated that 75% of the time there was a lint violation it was
> a real bug. *Although you have some rules to learn, it is quite
> a bit faster to find a bug at compile/lint time rather than having
> debug it in a simulator.
>
> Cheers,
> Jim
> --
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~
> Jim Lewis * *SynthWorks VHDL Training * *http://www.synthworks.com
>
> A bird in the hand may be worth two in the bush,
> but it sure makes it hard to type.


Thanks to Jim and Kevin for the feedback. It was quite helpful. In
particular using integers in place of vectors seems interesting (and
unusual to a Verilog person). I'll have to think about that.

Thanks again,
Mark
 
Reply With Quote
 
Mark Brehob
Guest
Posts: n/a
 
      01-28-2009
On Jan 28, 4:08*am, Jonathan Bromley <(E-Mail Removed)>
wrote:
> On Tue, 27 Jan 2009 17:33:44 -0800 (PST), Mark Brehob wrote:
> >Hello all,
> >I'm a teacher who has been teaching students Verilog for a while, but
> >for various reasons I've had to jump to VHDL for a certain course.

> [...]
> >#1 Why no process(*) statement similar to always@*?

>
> Others have answered, but... as a teacher, I trust
> you are aware of the various ways in which always@*
> is broken? *Move to SystemVerilog always_comb instead,
> if at all possible. *Most tools support it.
> --
> 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
> (E-Mail Removed)://www.MYCOMPANY.com
>
> The contents of this message may contain personal views which
> are not the views of Doulos Ltd., unless specifically stated.


Actually I'm unaware of @* being broken. Is it that @* doesn't handle
functions correctly? I've seen something about that, but we rarely
use functions, so...

In any case, could you elaborate?

Thanks,
Mark
 
Reply With Quote
 
Jan Decaluwe
Guest
Posts: n/a
 
      01-28-2009
Mark Brehob wrote:
> On Jan 27, 9:00 pm, Andreas Ehliar <(E-Mail Removed)> wrote:
>> On 2009-01-28, Mark Brehob <(E-Mail Removed)> wrote:
>>

>
>> And some encouragement: Think of how nice it will be to know that the
>> students' code will not contain any blocking/non-blocking races.
>>
>> /Andreas

>
> Actually, good coding style in Verilog completely eliminates that
> problem. In my other class, the students build a synthisizable out-of-
> order processor starting with an in-order processor. We've found that
> blocking/non-blocking problems just don't occur if you follow simple
> rules. We teach those rules as "required" and the problem go away.
> See http://www.eecs.umich.edu/courses/ee...guidelines.pdf
> for a short summary.


Simple enough, but especially intolerably simplistic.

Do you realize that these rules forbid variable semantics?
Even if you don't want to use variables in synthesizable code
for some awkward reason, you surely want them in test benches,
right? Don't you think you can have races there too? So what rule
do you use then?

No, even in Verilog you need something more sophisticated that
still permits variables: use signals (non-blocking assignments)
for communication, and variables (blocking assignments) for
local computation. It always works, for Verilog, VHDL, synthesis,
test bench, high-level modeling, you name it.

http://www.myhdl.org/doku.php/why#yo...nts_in_verilog


--
Jan Decaluwe - Resources bvba - http://www.jandecaluwe.com
Python as a hardware description language:
http://www.myhdl.org
 
Reply With Quote
 
georgek2000@gmail.com
Guest
Posts: n/a
 
      01-28-2009
On Jan 28, 6:17*am, Andreas Ehliar <(E-Mail Removed)> wrote:
> On 2009-01-28, Mark Brehob <(E-Mail Removed)> wrote:
>
> > Actually, good coding style in Verilog completely eliminates that
> > problem. *In my other class, the students build a synthisizable out-of-
> > order processor starting with an in-order processor. *We've found that
> > blocking/non-blocking problems just don't occur if you follow simple
> > rules. *We teach those rules as "required" and the problem go away.
> > Seehttp://www.eecs.umich.edu/courses/eecs470/tools/verilog_guidelines.pdf
> > for a short summary.

>
> Well, we teach more or less the same rules as well, but there is always
> at least one group per year who manages to come up with some nice and
> interesting blocking/non-blocking race condition
>
> The course you are talking about sounds very interesting by the way,
> I wish I could have attended such a course as an undergraduate student.
> Do you know roughly how much time students spend doing the projects in
> this course? *Do they have to care about the efficiency of their
> RTL code or do they only have to get it synthesizable?
>
> /Andreas


I recently read a text titled "FPGA Prototyping by Verilog
Examples." There is a section discussing the use/mixing of blocking/
no-blocking statements. Perhaps the best explanation I've seen. If
you have a chance, borrow it from a library and look at sections 7.1
and 7.2.

GK
 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      01-28-2009
Just remember to restrict the range of your integers (or subtypes), or
synthesis will promote everything to 32 bits signed (integer'range).
For an integer of unsigned(n-1 downto 0):

variable count : integer range 0 to 2**n-1;

I like to use the natural subtype just for more readability, but both
are equivalent:

variable count : natural range 0 to 2**n-1;

Also, expressions are promoted to 32 bit signed, only assignments are
restricted. So something like this works with natural subtypes, but
not with unsigned vectors:

if count - 1 < 0 then
do_something;
count := 2**n - 1;
else
count := count - 1;
end if;

This also has the benefit of automatically using the carry output from
the decrement logic, which is sometimes quicker and smaller. The two
decrementors from the comparison and the assignment end up being
shared in synthesis.

This also works for an up counter:

if count + 1 > 2**n-1 then
do_something;
count := 0;
else
count := count + 1;
end if;

Don't worry, because storage is limited to N bits, the operation's
promotion is pruned anyway.

Similarly, if you want integer arithmetic to rollover, you need to
tell it to do so:

count := (count - 1) mod 2**n; -- don't forget the parentheses!

In simulation, integer arithmetic is MUCH faster than vector
arithmetic.

Andy
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
VHDL-2002 vs VHDL-93 vs VHDL-87? afd VHDL 1 03-23-2007 09:33 AM
Verilog/VHDL Simulation Elf VHDL 1 10-10-2003 04:31 PM
dummy projects in VHDL/Verilog shumon VHDL 1 09-24-2003 01:41 AM
how to design this datapath unit for DSP using VHDL/Verilog? walala VHDL 3 08-30-2003 05:26 PM
where to find DCT/IDCT for JPEG/JPEG2000 VHDL/VERILOG source code? walala VHDL 0 08-01-2003 09:44 PM



Advertisments