Which to learn: Verilog vs. VHDL?

For small simulation of synthesizable design written in that wild mix, you can simulate in internal simulator of QuartusII 9.1 Web edition. Costs exactly 0 USD.

Reply to
Michael S
Loading thread data ...

VHDL plays ADA to Verilog's "C"

Reply to
Andrew Holme

Yes, which is seriously one of VHDL's strong points. (btw it's Ada not ADA, since it's a name not an acronym)

I am increasingly finding the synergy between Ada and VHDL to be very useful. I can now use a high level language on both sides of the HW/SW divide, even for low-level programming on AVR or MSP430 processors, and (unless a customer specifically asks for C) no longer bother with the tedious debugging and poor productivity that a low level language like C used to give.

I have experimentally called Ada code from VHDL, and vice versa, using the minimal VHPIDirect interface available in GHDL. The fact that GHDL uses GCC, which has very good Ada support, makes this easy. The link works both ways, but I haven't tried it with any other simulator.

This ought to allow me (when I get back to that project) to use the very clean object-oriented facilities of Ada-2005 to give the sort of constrained random test methodology that Janick Bergeron talks about in his "Writing Testbenches" book. It's not that I don't appreciate the OSVVM approach of doing it all in VHDL, but I believe that using inheritance and class extension allow much more reuse and faster test development.

- Brian

Reply to
Brian Drummond

What Verilog I know I got from "Verilog by Example" by Blaine C. Readler, which I thought was pretty good. Then again, I write VHDL pretty exclusively, and really only needed enough Verilog to be able to suss out what other people were doing.

In terms of which language is "better", one of the things I've been finding lately while I'm neck deep in Altera's tools is that, for Altera at least, Verilog support is a given whereas VHDL support is marginal at best. A lot of their fancier tools are only available in Verilog, or have glaring bugs in VHDL mode. This means that, if you write VHDL like I do, you're absolutely up a creek without a mixed language simulator.

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com 
Email address domain is currently out of order.  See above to fix.
Reply to
Rob Gaddi

I kinda agree with that statement, but it is relatively easy to get over th at hump. I started with Verilog a year ago after much experience with C. I was able to get up and running with Verilog in a short time (with the help of useful sample code that was close to what I was trying to do) while afte r about the same time spent with VHDL, I am nowhere as far along. There is something with VHDL that makes it appear unfriendly to people with C background. I started completely on my own with nobody to help me along, but I found Verilog really friendly. I do not have enough experience to say if one is superior to the other, but since at some point you will probably have to know both, start with Verilo g, it is less off-putting. For a plug (no financial interest, just a satisfied customer), look at the knjn.com kits and the related fpga4fun.com site.

Reply to
4rt.dw8.5t4wr

that hump. I started with Verilog a year ago after much experience with C. I was able to get up and running with Verilog in a short time (with the hel p of useful sample code that was close to what I was trying to do) while af ter about the same time spent with VHDL, I am nowhere as far along.

th C background. I started completely on my own with nobody to help me alon g, but I found Verilog really friendly.

ut since at some point you will probably have to know both, start with Veri log, it is less off-putting.

e knjn.com kits and the related fpga4fun.com site.

Reply to
4rt.dw8.5t4wr

background. I started completely on my own with nobody to help me along, but I found Verilog really friendly.

I think that "something" is verbosity. C allows you to, and C programmers seem to thrive on, writing extremely terse code.

while (!(c = *cptr++)) {...}

sorts of things abound, and are considered to be both clever and canonical. VHDL doesn't want you to, and doesn't encourage you to, and considers verbose code with lots of very explicit description of what's going on, to be an asset rather than a waste of keystrokes.

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com 
Email address domain is currently out of order.  See above to fix.
Reply to
Rob Gaddi

No, that isn't it.

For one, there are people using C as an HDL, which I don't find an especially good idea. (At least for the kinds of things I want to do, you can't port an algorithm from C code to HDL code.)

But VHDL seems to be verbose, especially in its declarations, in ways that both C and verilog are not.

Both C and verilog use &, |, and ^ for and, or, and xor operators. Maybe VHDL does, too. It is, though, fairly simple to learn to write verilog expressions, that is, the right hand side of continuous assignment statements, if you know C.

I don't know about others, but I generally write structural verilog with continuous assignment, and mostly not behavioral verilog, except for FF's (and state machines). Verilog has some operators that C doesn't have, but it isn't so hard to learn those, and they usually look like you might expect them to look like if C did have them.

As well as I remember them, the VHDL operators are somewhat different, and not easy for C programmers to remember.

Yes. I bought two books (about 20 years ago, so there weren't all that many choices) and with some synthesis tools and just started writing. Maybe it wouldn't have taken so much longer with VHDL, but it was pretty easy with verilog.

-- glen

Reply to
glen herrmannsfeldt

I have to admit, the biggest problem that I have as a C++ programmer when writing in either VHDL or Verilog is envy: in both (IIRC) VHDL or Verilog, when you have a module with a bazzilion input and output signals, you can invoke it with a syntax something like

module_name(module_signal_name = local_signal_name, ...)

In C++, when, for reasons of utility, you are forced to design a class whose constructor has a bazzilion inputs, you have to hold your breath, close your eyes, cross your fingers, and hope that whoever uses that constructor call gets all the right things in all the right places: I'd Much Rather be able to invoke the syntax above and have it all self- document.

--
My liberal friends think I'm a conservative kook. 
My conservative friends think I'm a liberal kook. 
Why am I not happy that they have found common ground? 

Tim Wescott, Communications, Control, Circuits & Software 
http://www.wescottdesign.com
Reply to
Tim Wescott

(big snip on verilog, VHDL, C, and the differences between them)

Fortran now has the keywork form as an option. Also, optional arguments so that the called routine can figure out which options are needed.

I do remember once mixing verilog and schematic capture. In that case, you have to use the keyword form, as there is no ordering to the ports in the schematic. (I tried to find one, but there isn't one.)

Also, some port names started with digits, which it turns out verilog allows, though I forget how you write them.

-- glen

Reply to
glen herrmannsfeldt

...

Not so easy? When you wanted to communicate the meaning of &, |, ^ above, I see you called them and, or, xor. Well, so does VHDL. I find it a whole lot easier to read.

And sufficiently more powerful that if you learn to use it (e.g. the type system) instead of fighting it, you can do things a lot more concisely. Using records for ports and hierarchical signals, for example, rather than passing lots of wires around.

Not that you could tell that concise VHDL was possible from any of the tutorial examples floating around, let alone an FPGA vendor's own code...

- Brian

Reply to
Brian Drummond

You mean named association?

If you want the option of named association in your object oriented software, that's easy : take a look at Ada-2005 (or now, Ada-2012).

It gives you a lot of other good stuff too - including a remarkably sane object-oriented programming model (where everything ISN'T a pointer), and spookily accurate reports from runtime faults that would just say "segfault" in a C++ program.

The one positive thing C++ has given us: you can't say Ada is too complex any more!

- Brian.

Reply to
Brian Drummond

C, since C99, has designated initializers for aggregate types, which helps pull off this syntactic sugar.

#include

struct test_parameter { int a; float b; };

void test(struct test_parameter p) { printf("testing a: %d, b: %f\n", p.a, p.b); }

int main(void) { test((struct test_parameter){.a = 1, .b = 2.0f}); test((struct test_parameter){.b = 5.0f, .a = 4}); return 0; }

C++ doesn't support C's designated initializers, so this trick can't be pulled with it. Nevertheless, as I've mentioned previously, the named parameter idiom can be used for the exact same effect.

This means that it isn't true that C++ forces anyone to design a class with a bazzilion parameters. If having to pass more than a couple of parameters to a constructor becomes a problem, there are plenty of ways to avoid that. For example, it is also possible to use Boost's ad-hoc implementation of named parameters:

formatting link

What I tend to use to avoid having to define multiple versions of the same constructor or a constructor with a bazzilion parameters is to use a named parameter idiom to define a parameter class for the constructor, such as:

#include

class Foo { int a; float b;

public: struct Parameters { int a; float b; Parameters & length(int const l) {a = l; return

*this;} ; Parameters & frequency(float const f) {b = f; return *this;}; };

Foo(Parameters const &param): a(param.a), b(param.b) { std::cout - if named

Adding support in the core language for named parameters would only make them easier to write because there would be no need to define a named parameter idiom class. Yet, they aren't hard to define to begin with.

Named parameters in the core language aren't any easier to use than a named parameter idiom class. For example:

f = OpenFile("foo.txt", blockSize = 1024);

vs

f = OpenFile("foo.txt", OpenFile::Param().blockSize(1024) );

or

f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) );

In addition, the named parameter idiom makes it possible to define methods which operate on multiple parameters. For example, in the above example, it's possible to define the following member function:

OpenFile::Param &OpenFile::Param::defaultFile(std::string &file) { /*stuff*/}

This would mean that the following examples would be equivalent:

f = OpenFile(OpenFile::Param().file("foo.txt").blockSize(1024) ); f = OpenFile(OpenFile::Param().defaultFile("foo.txt") );

You can't do that with named parameters.

There is no way to be sure about that. For example, OpenFile might be an implementation of a strategy pattern.

I don't know if the C++ standard committee is reluctant to add new features. If I'm not mistaken, the only instance where new features stopped being considered was near the end of C++0x's standardization process, and even then these suggestions were only postponed so that C++11 could be finally published without any further delay.

In addition, if the C++ standard committee was reluctant to add new features then they wouldn't be opened to new proposals:

formatting link

I really doubt that named parameters would be easy to add to the language, considering C++'s support for function overloading. Take, for example, the following class:

struct Bar { void baz(int a, float b) { /* nothing happens */ } void baz(float b, int a) { /* the enter key blows up */ } };

int main(void) { Bar bar; bar.baz( a = 10, b = 20 ); return 0; }

What member function do you expect to be called?

C++ doesn't support named parameters in the core language, but to go from there and claim that the named parameter idiom isn't "proper support" is a bit of a stretch. The only claim that you can really make is that named parameters aren't supported directly in the core language, or that C++ isn't exactly like, say, Python. Yet, none of those complains are valid or reasonable.

Rui Maciel

Reply to
Rui Maciel

The named parameter idiom can give a /similar/ effect - but might be less efficient (code space and run-time speed), and is certainly massively less compact and elegant in the source code.

The use of C structs with designated initialisers gives a much more elegant solution than the C++ "named parameter idiom". But it is still far from ideal - as well as requiring a bit more unnecessary coding, you might get a less efficient implementation (depending on the compiler and the target, passing a struct is likely to be less efficient than passing arguments directly, and it limits the compiler's optimiser).

And as you note, C++ doesn't support designated initialisers for structs. I can't see any rational reason why it should not, but I suppose the C++ standards people have some reason (other than to annoy people who want to write code that works as C and C++).

I can see how this all works - and I can see how the named parameter idiom (or related solutions) can sometimes be better than nothing.

But I /cannot/ see why anyone would prefer a solution above instead of:

class Foo { int a; float b; public: Foo(int length, float frequency) : a(length), b(frequency) { } };

int main(void) { Foo(length = 2, frequency = 4); Foo(frequency = 5, length = 3); }

Is there any good reason why that syntax is not supported by C++ (and C, though it is much more useful if support for default parameters were added)?

I suppose it might be argued that "Foo(.length = 2, .frequency = 4);" would be more consistent with C's designated initialisers for structs - I think most users would be happy either way.

Look above at your "Foo" class, and my "Foo" class. Every character that you wrote, but that I did not write, fills the source code unnecessarily. In my suggested code, /nothing/ extra needs to be added to support designated parameters - they are totally free to the programmer (both in the source code, and in generated code space and time). So I think a "lot of mess" is justified - your solution uses more lines of code to implement the named parameters than to implement the class (though clearly the relative impact would be less in real code). As always, extra code like this means less readability and more effort in programming.

Can't you see that my suggestion is shorter and clearer? You could argue that it is not /much/ shorter, or not /much/ clearer - that's a question of taste and experience.

Can't you see that my suggestion is completely /free/ for the programmer

- they get the benefits of named parameters for /every/ function and method, without any changes or additions to the source code? Clearly, adding named parameter idiom classes to a significant number of functions in your code would overwhelm your code with "bookkeeping" code to enable the idiom.

I can well agree that the current named parameter idiom has some uses, where the clarity for the caller over normal positional parameters justifies the effort of implementing it. But adding it to the core language would be far better.

I don't quite get your example here, but I can certainly see that there are times you might still want to use the idiom. Perhaps setting the parameter would have other side-effects, or perhaps you want multiple arguments in the parameter function.

But obviously there is nothing in my suggested language change that would limit the use of named parameter idiom classes. Simple named parameters would cover 99% of the use cases - and you can still use the old idiom classes for the remaining 1%.

They /are/ reluctant to add new features to the core language - and that is normally a good thing, as the language is complicated enough as it is. They will add new features if they feel they need to - such as lambdas and new reference types in C++11. But they insist on a lot of justification.

Perhaps no one has submitted a proposal for named parameters to the committee - I know /I/ certainly have not done so. Maybe everyone thinks it is such an obvious, cost-free and useful feature that someone else must have submitted it already.

Code like that is already broken - which member function should be called for bar.baz(10, 20)? (Even if the answer is well-defined in C++ at the moment, it is still wrong IMHO because the code is unclear.)

But you are certainly right here - there will be complications in the face of function overloading, that will make it harder to implement than I first imagined. I can't see it being an impossible problem, however - but there will be some cases (like that example) when the only decent thing the compiler can do is issue an error about ambiguous overloads.

Well, I think the second and third claims here /are/ valid and reasonable - named parameters are clearly not supported in the core C++ language, and the way you make named parameters work in today's C++ is clearly not the same as in Python.

And as for my main claim that the named parameter idiom is not "proper support" for named parameters - that's a matter of opinion, and our opinions obviously differ here.

mvh.,

David

Reply to
David Brown

I agree. I do embedded programming. I can't afford to bloat my code, or slow down my execution, with workarounds like this.

--
Tim Wescott 
Control system and signal processing consulting 
www.wescottdesign.com
Reply to
Tim Wescott

Having developed in VHDL (RTL and verification) for over 20 yrs, I recently took a two week intensive course in Verilog, SystemVerilog and UVM. I have a newfound appreciation for just how nice VHDL really is! Verilog has so m any rabbit holes that look like they should work, but don't, and if you don 't use a separate linter, you'll never find them. Add to that the lack of s ubprogram overloading, unconstrained array types (including inspection of a rguments to determine array range, etc.) and a host of other features I've taken for granted for so many years, and its a now brainer.

If systemverilog did not have all the baggage of verilog, it might be a pre tty good language. Take a look and the scheduling model for SystemVerilog: it is a total mish-mash of bolted-on steps to handle this problem or that. And if systemverilog is so powerfull, why is the preprocessor so integral t o a standard class library and use model like UVM? Pre-processors are crutc hes for hobbling along on the broken limbs of ill-conceived or incomplete l anguages.

Perhaps the most glaring ommission of verilog/SV is the lack of bounds chec king on array indices and scalar arguments to subprograms. This feature alo ne allows VHDL to give you an error message that identifies where the probl ems is, rather than simply strange behavior, or a segmentation fault in ver ilog/SV.

Take this example: try doing what the synthesizeable, standard VHDL fixed a nd floating point packages do, in verilog or even system verilog. And keep in mind that the first versions (complete functionality) were all done in t he 20 year old '93 version of VHDL! The 2008 version only added generics to the packages for default handling of saturation, rounding, etc.

The other issue that struck me during the course was the common reliance up on the pre-processor in the lab examples to ensure compatibility with sever al different brands of simulators. What works in one simulator, doesn't al ways work in another! And these are all "compliant" simulators! A leisurely stroll through the VHDL and SystemVerilog LRMs reveals the difference: The VHDL strictly defines what the language does and what is not allowed, with very few ambiguities. The SV LRM replaces strict specification with usage examples, and hopes that each developer gets the same idea about what to su pport and what to disallow. Ever seen an SV compliance suite?

Does VHDL have room for improvement? Absolutely! It needs an object-oriente d capability complete with inheritance. Existing protected types are a star t (see OSVVM.org for an example of what can be accomplished with them), but no substitute for a complete OO implementation. An interface capability fo r multi-directional elements on ports of record type is also needed (one of the nice features of systemverilog). The good news is these and other issu es are being worked today for the next version of VHDL.

Andy

Reply to
jonesandy

Rabbit holes ... I like it! that was my impression on the brief look I took at Verilog, and I have never had to use it (other than adding DDR2 memories to my VHDL projects).

And there is a very good model to follow in Ada-2005 - I hope those in charge know of it. Goes both ways ... VHDL-2008 beat Ada to conditional and case-expressions (now in Ada-2012 ... admittedly also in Algol-W from

1963!)

Would also be nice to see an interface to proof tools, along the lines of SPARK in Ada - especially since the provable subset of Ada and the synthesisable subset of VHDL have quite a lot in common.

- Brian

Reply to
Brian Drummond

From that I learn that so far you managed to avoid qsys.

d

Yesterday I looked (again) at VHDL-2008 additions. I like few of them. In particular, unconstrained arrays in records (and other arrays) remove one of the last reasons to avoid defining entity ports as records. Unconstrained arrays of unconstrained arrays also look useful and probably had to be part of the language from the very beginning. By comparison to 2 items above, (all) specification in sensitivity list may look as minor addition, but until now those error-prone sensitivity list were the main reason for me to avoid combinatorial processes altogether. Now I can reconsider.

So, I'd like to use VHDL-2008. Altera integrated synthesis even appear to support all features that I care about. But there remains a question of simulation. Does ModelSim Altera Edition support them? What about ModelSim Altera Starter Edition?

I don't consider proof tools particularly useful.

Reply to
Michael S

Apparently it's an Altera tool. Yes I have, so far.

I think it's a harmless addition, but I've never found a role for combinational processes anyway!

Understandable. They have been around since the 80s, but it's only in the last couple of years they have started to gain any traction.

- Brian

Reply to
Brian Drummond

2

I am thinking about one specific use case. signal bar, bar0, bar1 : bar_record_t; begin x:foo1 port map (..., bar_out => bar);

process (all) begin bar0

Reply to
Michael S

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.