FPGARelated.com
Forums

Which to learn: Verilog vs. VHDL?

Started by Michael April 14, 2008
On Mon, 07 Jan 2013 10:47:43 -0800, jonesandy wrote:

> 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 many 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.
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).
> Does VHDL have room for improvement? Absolutely! It needs an > object-oriented capability complete with inheritance. Existing protected > types are a start (see OSVVM.org for an example of what can be > accomplished with them), but no substitute for a complete OO > implementation.
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
On Jan 8, 3:02=A0am, Brian Drummond <br...@shapes.demon.co.uk> wrote:
> On Mon, 07 Jan 2013 10:47:43 -0800, jonesandy wrote: > > 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 many 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. > > 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).
From that I learn that so far you managed to avoid qsys.
> > > Does VHDL have room for improvement? Absolutely! It needs an > > object-oriented capability complete with inheritance. Existing protecte=
d
> > types are a start (see OSVVM.org for an example of what can be > > accomplished with them), but no substitute for a complete OO > > implementation. > > 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!)
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?
> > 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
I don't consider proof tools particularly useful.
On Wed, 09 Jan 2013 04:59:25 -0800, Michael S wrote:

> On Jan 8, 3:02&nbsp;am, Brian Drummond <br...@shapes.demon.co.uk> wrote: >> On Mon, 07 Jan 2013 10:47:43 -0800, jonesandy wrote: >> > Verilog has so many 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. >> >> 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). > > From that I learn that so far you managed to avoid qsys.
Apparently it's an Altera tool. Yes I have, so far.
> Yesterday I looked (again) at VHDL-2008 additions. > I like few of them.
> 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.
I think it's a harmless addition, but I've never found a role for combinational processes anyway!
>> Would also be nice to see an interface to proof tools, along the lines >> of SPARK > I don't consider proof tools particularly useful.
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
On Jan 10, 2:28=A0am, Brian Drummond <br...@shapes.demon.co.uk> wrote:
> On Wed, 09 Jan 2013 04:59:25 -0800, Michael S wrote: > > On Jan 8, 3:02=A0am, Brian Drummond <br...@shapes.demon.co.uk> wrote: > >> On Mon, 07 Jan 2013 10:47:43 -0800, jonesandy wrote: > >> > =A0Verilog has so many 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. > > >> 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 DDR=
2
> >> memories to my VHDL projects). > > > From that I learn that so far you managed to avoid qsys. > > Apparently it's an Altera tool. Yes I have, so far. > > > Yesterday I looked (again) at VHDL-2008 additions. > > I like few of them. > > 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. > > I think it's a harmless addition, but I've never found a role for > combinational processes anyway! >
I am thinking about one specific use case. <code> signal bar, bar0, bar1 : bar_record_t; begin x:foo1 port map (..., bar_out =3D> bar); process (all) begin bar0 <=3D bar; bar1 <=3D bar; bar0.valid <=3D bar.valid and not addr(5); bar1.valid <=3D bar.valid and addr(5); end process; y0:foo2 port map (bar_inp =3D> bar0, ...); y1:foo2 port map (bar_inp =3D> bar1, ...); </code> Pay attention that combinatorial process is required only because of not sufficiently powerful syntax for concurrent assignment of record types. I'd very much prefer to write (outside of the process) something like: bar0 <=3D (valid =3D> bar.valid and not addr(5), others =3D> from bar); May be, in the next VHDL edition?
On Thu, 10 Jan 2013 02:35:05 -0800, Michael S wrote:

> On Jan 10, 2:28&nbsp;am, Brian Drummond <br...@shapes.demon.co.uk> wrote: >> On Wed, 09 Jan 2013 04:59:25 -0800, Michael S wrote:
>> > Yesterday I looked (again) at VHDL-2008 additions. >> > 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. >> >> I think it's a harmless addition, but I've never found a role for >> combinational processes anyway!
> I am thinking about one specific use case. > <code>
I can see the rationale for that use case.
> I'd very much prefer to write (outside of the process) something like: > bar0 <= (valid => bar.valid and not addr(5), others => from bar);
I appreciate the desire for this in a future VHDL. Meanwhile, this is a good place for a function. It can be declared locally, but my solution is to treat bar_record_t as an abstract type. Wrap it in a package along with functions to manipulate it. package bar_type is type bar_record_t is... function validate (B : bar_record_t; V : bar_valid_t) return bar_record_t; ... end bar_type; -- in the package body function validate (B : bar_record_t; V : bar_valid_t) return bar_record_t is variable temp: bar_record_t := B; begin temp.valid := V; return temp; end validate; Then the main code simply reads: bar0 <= bar_type.validate(bar, bar.valid and not addr(5)); bar1 <= bar_type.validate(bar, bar.valid and addr(5)); To my eyes, this makes the main code cleaner, so I wouldn't even contemplate a combinational process here. - Brian
On Jan 10, 3:27=A0pm, Brian Drummond <br...@shapes.demon.co.uk> wrote:
> On Thu, 10 Jan 2013 02:35:05 -0800, Michael S wrote: > > On Jan 10, 2:28=A0am, Brian Drummond <br...@shapes.demon.co.uk> wrote: > >> On Wed, 09 Jan 2013 04:59:25 -0800, Michael S wrote: > >> > Yesterday I looked (again) at VHDL-2008 additions. > >> > 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. > > >> I think it's a harmless addition, but I've never found a role for > >> combinational processes anyway! > > I am thinking about one specific use case. > > <code> > > I can see the rationale for that use case. > > > I'd very much prefer to write (outside of the process) something like: > > bar0 <=3D (valid =3D> bar.valid and not addr(5), others =3D> from bar); > > I appreciate the desire for this in a future VHDL. > > Meanwhile, this is a good place for a function. > > It can be declared locally, but my solution is to treat bar_record_t as > an abstract type. Wrap it in a package along with functions to manipulate > it. > > package bar_type is > type bar_record_t is... > function validate (B : bar_record_t; V : bar_valid_t) > =A0 =A0 =A0 =A0 =A0return bar_record_t; > ... > end bar_type; > > -- in the package body > function validate (B : bar_record_t; V : bar_valid_t) > =A0 =A0 =A0 =A0 =A0return bar_record_t is > =A0 =A0variable temp: bar_record_t :=3D B; > begin > =A0 =A0temp.valid :=3D V; > =A0 =A0return temp; > end validate; > > Then the main code simply reads: > > bar0 <=3D bar_type.validate(bar, bar.valid and not addr(5)); > bar1 <=3D bar_type.validate(bar, bar.valid and addr(5)); > > To my eyes, this makes the main code cleaner, so I wouldn't even > contemplate a combinational process here. > > - Brian
That's what I do today, more or less. Except I prefer to keep things as local as possible, so, unless it is used by more than one entity, I'll not put validate() function into package. It works, but it takes few minutes when writing code - not a big deal. More importantly, when reading a code, understanding what's going on takes few tens of second, unless similar technique already appeared many times in the project an the reader already caught with writer's patterns. BTW, in order to facilitate reader's pattern recognition I'd call the helper function set_valid() rather than validate(). The advantage of built in tool, i.e. non-existent "others=3D>from" syntax, is that reader already knows what it means. The advantage of solution with combinatorial process is that although reader does not know what it means, he is able to figure it out without jumping back and and force between different source LOCs and files.
On Thu, 10 Jan 2013 07:14:54 -0800, Michael S wrote:

> On Jan 10, 3:27&nbsp;pm, Brian Drummond <br...@shapes.demon.co.uk> wrote:
>> function validate (B : bar_record_t; V : bar_valid_t) >> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;return bar_record_t;
...
>> Then the main code simply reads: >> >> bar0 <= bar_type.validate(bar, bar.valid and not addr(5)); >> bar1 <= bar_type.validate(bar, bar.valid and addr(5)); >> >> To my eyes, this makes the main code cleaner, so I wouldn't even >> contemplate a combinational process here. > > That's what I do today, more or less. Except I prefer to keep things as > local as possible, so, unless it is used by more than one entity, I'll > not put validate() function into package.
Fair enough - for single uses, I do use locally declared functions too.
> It works, but it takes few minutes when writing code - not a big deal. > More importantly, when reading a code, understanding what's going on > takes few tens of second, unless ...the reader already caught with > writer's patterns.
A good argument for adopting a small and consistent set of patterns!
> BTW, in order to facilitate reader's pattern recognition I'd call the > helper function set_valid() rather than validate().
It's your example; you have the context to name it better than I do!
> The advantage of built in tool, i.e. non-existent "others=>from" syntax, > is that reader already knows what it means.
However you won't be able to sell anyone the idea of a new reserved word "from" on such a lightweight justification. How about "others => bar.others" instead? Equally clear, I think, and quite in keeping with the language. - Brian
On Fri, 11 Jan 2013 00:22:53 +0000 (UTC)
Brian Drummond <brian@shapes.demon.co.uk> wrote:

> On Thu, 10 Jan 2013 07:14:54 -0800, Michael S wrote: >=20 > > On Jan 10, 3:27=C2=A0pm, Brian Drummond <br...@shapes.demon.co.uk> wrot=
e:
>=20 > >> function validate (B : bar_record_t; V : bar_valid_t) > >> =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0return bar_record_t; > ... > >> Then the main code simply reads: > >> > >> bar0 <=3D bar_type.validate(bar, bar.valid and not addr(5)); > >> bar1 <=3D bar_type.validate(bar, bar.valid and addr(5)); > >> > >> To my eyes, this makes the main code cleaner, so I wouldn't even > >> contemplate a combinational process here. > > > > That's what I do today, more or less. Except I prefer to keep things as > > local as possible, so, unless it is used by more than one entity, I'll > > not put validate() function into package. >=20 > Fair enough - for single uses, I do use locally declared functions too. >=20 > > It works, but it takes few minutes when writing code - not a big deal. > > More importantly, when reading a code, understanding what's going on > > takes few tens of second, unless ...the reader already caught with=20 > > writer's patterns. >=20 > A good argument for adopting a small and consistent set of patterns! >=20 > > BTW, in order to facilitate reader's pattern recognition I'd call the > > helper function set_valid() rather than validate(). >=20 > It's your example; you have the context to name it better than I do! >=20 > > The advantage of built in tool, i.e. non-existent "others=3D>from" synt=
ax,
> > is that reader already knows what it means. >=20 > However you won't be able to sell anyone the idea of a new reserved word=
=20
> "from" on such a lightweight justification.=20 > How about "others =3D> bar.others" instead?=20 >=20 > Equally clear, I think, and quite in keeping with the language. >=20 > - Brian
Or others =3D> unaffected --=20 Rob Gaddi, Highland Technology -- www.highlandtechnology.com Email address domain is currently out of order. See above to fix.
On Jan 11, 2:26=A0am, Rob Gaddi <rga...@technologyhighland.invalid>
wrote:
> On Fri, 11 Jan 2013 00:22:53 +0000 (UTC) > > > > > > > > > > Brian Drummond <br...@shapes.demon.co.uk> wrote: > > On Thu, 10 Jan 2013 07:14:54 -0800, Michael S wrote: > > > > On Jan 10, 3:27=A0pm, Brian Drummond <br...@shapes.demon.co.uk> wrote=
:
> > > >> function validate (B : bar_record_t; V : bar_valid_t) > > >> =A0 =A0 =A0 =A0 =A0return bar_record_t; > > ... > > >> Then the main code simply reads: > > > >> bar0 <=3D bar_type.validate(bar, bar.valid and not addr(5)); > > >> bar1 <=3D bar_type.validate(bar, bar.valid and addr(5)); > > > >> To my eyes, this makes the main code cleaner, so I wouldn't even > > >> contemplate a combinational process here. > > > > That's what I do today, more or less. Except I prefer to keep things =
as
> > > local as possible, so, unless it is used by more than one entity, I'l=
l
> > > not put validate() function into package. > > > Fair enough - for single uses, I do use locally declared functions too. > > > > It works, but it takes few minutes when writing code - not a big deal=
.
> > > More importantly, when reading a code, =A0understanding what's going =
on
> > > takes few tens of second, unless ...the reader already caught with > > > writer's patterns. > > > A good argument for adopting a small and consistent set of patterns! > > > > BTW, in order to facilitate reader's pattern recognition I'd call the > > > helper function set_valid() rather than validate(). > > > It's your example; you have the context to name it better than I do! > > > > The advantage of built in tool, i.e. non-existent "others=3D>from" sy=
ntax,
> > > is that reader already knows what it means. > > > However you won't be able to sell anyone the idea of a new reserved wor=
d
> > "from" on such a lightweight justification. > > How about "others =3D> bar.others" instead? > > > Equally clear, I think, and quite in keeping with the language. > > > - Brian > > Or others =3D> unaffected >
Why unaffected? I want other fields of bar1 to get values from bar. Remember, we are discussing concurrent assignments, not assignments in the process