VHDL newbie: building sequential circuits with basic gates

Hey everyone,

As an assignment for a course in my CS degree, I have to build a D latch, a D flip flop and a 1 bit register with VHDL. I have been given the "process" versions of those and I have to rewrite them using elementary gates and feedback connections.

My teachers are not really profficient in the topic (sadly) but we are going through hoops to get stuff working. I have read on several pages that because of limitations in VHDL simulations, basic sequential circuits such as the latch/ff should not be implemented with gates but using processes instead.

We are sure that the circuits we described using the component-based approach in VHDL correctly mimic the hardware versions of those. Still, behaviours are erratic and GHDL is giving away cryptic "stop- delta" compilation errors that we can't fix.

This appears to be somewhat confirmed by the fact that this page (the only one I've been able to find that provides a gate-based implementation of latches and ffs) does it with some obscure library reference that I have not available (lsi_10k) and a complicated definitions instead of usual signaling and port mapping with and's and not's.

formatting link

Feel free to browse through the code by checking out with anonymous SVN: $ svn checkout

formatting link
orga1-2007 You can then run "make tb_reg1bit" and examine the resulting VCD to see what's going on.

I am using this version at home, but the same problems arise with the debian etch versions at my college: GHDL 0.26 (20070408) [Sokcho edition] Compiled with GNAT Version: 4.1.220061115prerelease

My knowledge of VHDL is very close to nil and documentation appears very sparse on the web. I could really use some help, so thanks in advance for reading.

Gonzalo

Reply to
GomoX
Loading thread data ...

Which topic? Boolean logic or VHDL?

Does 'working' mean that the simulation is correct or does it mean that actual hardware has been built and tested? The advice that you'll get kind of depends on that (more on that later).

The limitation comes about because of the interaction of two things:

  1. Simulation allows for zero propogation delays through logic
  2. The logic type most commonly used (i.e. std_logic) allows signals to be 'unknown'.

Neither of these two things model the real world behaviour of anything at all....and yet they are both powerful aids for designing logic properly and are 'good' things from a design perspective.

Try simulating the simplest feedback element available, the oscillator. The logic to describe it is x

See above discussion for the likely cause of the error.

Nothing complicated is needed. If this is a simulation only type of assignment that you're doing then you simply need to avoid #1 and #2. To get around #1 you make sure that every logical operation has a non zero propogation delay (or at least somewhere in your feedback loop there is a non-zero delay for every possible path). To get around #2 you need to not use std_logic type, use a logic type that only has two states.

If this is intended to be built into real hardware though, don't do either of those two things. Designing a feedback loop of anything without a proper storage element will always result in flaky behaviour at best. How you implement it is also be a function of which target technology you're planning on implementing it in (hence all the postings that you've seen discouraging building flops out of gates). Since you didn't mention anything about a target device I'm guessing that this might be a simulation only assignment but in case it's not I added this caution.

Kevin Jennings

Reply to
KJ

Back to basics ... so look at the source materials from when those were the basic building blocks.

If you have access to a university library (or even a decently stocked engineer's bookshelf) you could do a lot worse than looking at the original Texas Instruments TTL Data Book.

Or maybe you can find the 7474 or 74LS74 datasheets online? Google is your friend...

formatting link
and look at the Motorola one for example

- Brian

Reply to
Brian Drummond

In news:hWW2i.1605$ snipped-for-privacy@newssvr19.news.prodigy.net timestamped Thu,

17 May 2007 07:22:50 -0400, "KJ" posted: "[..] [..]
  1. Simulation allows for zero propogation delays through logic
  2. The logic type most commonly used (i.e. std_logic) allows signals to be 'unknown'.

Neither of these two things model the real world behaviour of anything at all....and yet they are both powerful aids for designing logic properly and are 'good' things from a design perspective.

[..]"

Hi,

How can zero delays or std_logic be useful?

Regards, Colin Paul Gloster

Reply to
Colin Paul Gloster

Yes, you really don't want to do that. Looping back a combinatorial output makes a sort of infinite loop of dependencies for the simulator to try to make sense of. In the real world it works because of delay and capacitance and stuff like that, but an HDL simulator it's not designed to do physical modeling of actual devices! Instead it's designed to simulate the application-level behaviour of devices that can be reasonably represented with just a few paramaters (like propogation delay), and having just a few states, (like 1, 0, undriven, and unkown)

If you want to do something like what you are talking about, try playing with software that's designed to simulate the analog behaviour of real devices, which is to say spice. Get yourself some simple logic gate circuits to put in a spice deck and play with graphing how that responds over time to "digital" inputs.

Reply to
cs_posting

If you *must* build gate models in VHDL, be sure to include a delay in your gate, eg OUT

Reply to
David R Brooks

Because they allow you to create a simulation of your circuit at a level of abstraction removed from those details. If you follow a standard synchronous design template, you can then use a synthesiser to get a netlist that does the same thing as your simulations.

Lots of us do it all the time :-)

Cheers, Martin

--
martin.j.thompson@trw.com 
TRW Conekt - Consultancy in Engineering, Knowledge and Technology
http://www.conekt.net/electronics.html
Reply to
Martin Thompson

As to how zero delays can be useful, I'd say that from the perspective of designing logic to implement a particular function the delay used is usually irrelevant so zero delay is just as useful as 1 ns, 1 ps, or any other delay. If there was some 'default' non-zero delay built into the design language or the simulator then no doubt that default time will just get in the way of somebody trying to create some new design at some point because they are trying to design something that needs to run at or near a speed that is comparable to this 'default' time. The definition of 'delta time' which is infintesimally small and simply represents extra churns by the simulation engine that are still completed in 'zero time' permanently gets around this issue. The fact that zero delay is not physically possible in the real world just never gets in the way of designing whatever it is that you're designing.

std_logic (and std_ulogic) are useful because of the meta-logical values like 'Z', 'U', and 'X' even though in the real world, logical signals will never be 'U' or 'X', they will always be at a voltage/current level that corresponds to a logical '0' or '1' or tri-stated. The 'unknowns' are great because when you're testing your design in simulation those unknown values will propogate through the logic and allow for very rapid determination of logic holes in the design. Using a type such as 'boolean' or 'bit' to do your design would result in these signals getting assigned default values that may or may not correspond to what a real device would do and yet by virtue of whatever value happened to get assigned, this may cause downstream logic to appear to behave properly in simulation but fail in the real world. This is the types of thing that the 'unknowns' flush out quite quickly

From a modelling perspective, when you're trying to create a behavioural model of some existing thing the opposite can usually apply. 'Zero' delays and 'unknowns' for logic don't have much value. Since the original poster was querying about constructing storage elements from basic logic gates, this would fall into the 'modelling side' rather than the 'design side' of things so I put my 2 cents in with that in mind and added the caution about not trying to use that advice if you're doing design.

Kevin Jennings

Reply to
KJ

In news:rzN3i.3708$ snipped-for-privacy@newssvr19.news.prodigy.net timestamped Sat,

19 May 2007 21:33:08 -0400, "KJ" posted: "[..]

As to how zero delays can be useful, I'd say that from the perspective of designing logic to implement a particular function the delay used is usually irrelevant so zero delay is just as useful as 1 ns, 1 ps, or any other delay. [..]"

Thank you for the insightful answer re zero delays.

"std_logic (and std_ulogic) are useful because of the meta-logical values like 'Z', 'U', and 'X' even though in the real world, logical signals will never be 'U' or 'X', they will always be at a voltage/current level that corresponds to a logical '0' or '1' or tri-stated. The 'unknowns' are great because when you're testing your design in simulation those unknown values will propogate through the logic and allow for very rapid determination of logic holes in the design. Using a type such as 'boolean' or 'bit' to do your design would result in these signals getting assigned default values [..]

[..]"

This is more an explanation of how std_logic is better than Boolean or bit instead of an explanation of how std_logic could be considered to be useful, as all of those advantages apply to std_ulogic as well and std_ulogic seems to be better, which you stated in news:eLUEh.2278$ snipped-for-privacy@newssvr25.news.prodigy.net in February 2007.

Regards, Colin Paul Gloster

Reply to
Colin Paul Gloster

I guess I'm not sure what you're getting at. It sounds like you accept my explanation of how std_logic is better than boolean or bit in the particular context that I've described but are not accepting that as being evidence of std_logic being 'useful'.

std_logic and std_ulogic share all of the same advantages and disadvantages as they relate to the particular point of propagating 'unknown' logic levels. I didn't distinguish between the two here since the essential element was that the original poster had questions related to modelling and by necessity was going to be creating combinatorial feedback paths in order to create those models just like how it is done in an actual part. The question seemed to be about how their are 'issues' in doing this and all I was doing was clarifying those issues as they related to the particular context of modelling storage elements as the poster was instructed to do.

The earlier discussion about std_ulogic having advantages over std_logic that you referenced was in a totally different context, that of design. While all of those advantages and disadvantages also apply to most situations when modelling device behaviour, one particular situation where they have a huge disadvantage is when modelling a combinatorial feedback path as the original poster was trying to do.

Another example of such a difference between when a particular type is good to use or not would be between the use of type 'unsigned' or type 'natural' when creating a counter (or adder). In the hands of the more skilled designer, type 'natural' is usually preferred; in the hands of the less skilled the use of type 'natural' can cause problems because signals of type natural will always magically initialize to 0 in simulation. In a real device that might not happen to guarantee such behaviour and for which the less skilled designer has forgotten to design in a path to reset the counter they can run into issues when trying to get their stuff working on a real board. Had that less skilled designer instead used an 'unsigned' type for the counter they would have cleared up the design issues during simulation because the forgotten reset path would have caused them to have 'unknowns' that need to be cleared up. Here the difference in context is not the design itself, it's not design versus modelling.it is simply the skill of the designer. So which is the 'better' choice? You could say it's 'unsigned' but there is a simulation performance penalty to be paid in using 'unsigned' over 'natural'. So is that performance penalty a 'good' thing if you have a skilled designer? Maybe not.

The bottom line is each data type is 'useful' and probably in some sense 'better' than any other data type in a particular context, but may fall flat when used in a different context.

Kevin Jennings

Reply to
KJ

In news:XX24i.1173$ snipped-for-privacy@newssvr22.news.prodigy.net timestamped Sun,

20 May 2007 17:19:47 -0400, "KJ" posted: "[..] I guess I'm not sure what you're getting at. It sounds like you accept my explanation of how std_logic is better than boolean or bit in the particular context that I've described but are not accepting that as being evidence of std_logic being 'useful'."

Yes.

"std_logic and std_ulogic share all of the same advantages and disadvantages as they relate to the particular point of propagating 'unknown' logic levels. I didn't distinguish between the two here since the essential element was that the original poster had questions related to modelling and by necessity was going to be creating combinatorial feedback paths in order to create those models just like how it is done in an actual part. The question seemed to be about how their are 'issues' in doing this and all I was doing was clarifying those issues as they related to the particular context of modelling storage elements as the poster was instructed to do.

The earlier discussion about std_ulogic having advantages over std_logic that you referenced was in a totally different context, that of design."

Ah, I had not realized that std_ulogic is better than std_logic for design but not modelling.

"While all of those advantages and disadvantages also apply to most situations when modelling device behaviour, one particular situation where they have a huge disadvantage is when modelling a combinatorial feedback path as the original poster was trying to do."

Just to clarify: does std_ulogic have a huge disadvantage in contrast to std_logic when modelling combinatorial feedback?

"[..] In the hands of the more skilled designer, type 'natural' is usually preferred; in the hands of the less skilled the use of type 'natural' can cause problems because signals of type natural will always magically initialize to 0 in simulation. In a real device that might not happen to guarantee such behaviour and for which the less skilled designer has forgotten to design in a path to reset the counter they can run into issues when trying to get their stuff working on a real board. Had that less skilled designer instead used an 'unsigned' type for the counter they would have cleared up the design issues during simulation because the forgotten reset path would have caused them to have 'unknowns' that need to be cleared up. Here the difference in context is not the design itself, it's not design versus modelling.it is simply the skill of the designer."

I understand and may agree with this point but I disagree with the particular example as being an issue of skill... I would classify this as more of an issue of whether the designers know what their tools do.

"[..]

The bottom line is each data type is 'useful' and probably in some sense 'better' than any other data type in a particular context, but may fall flat when used in a different context."

Understood.

Thanks, Colin Paul Gloster

Reply to
Colin Paul Gloster

No disadvantages that I can think of.

I understand and may agree with this point but I disagree with the

Knowledge of what the tools do and how best to use those tools is part of what I would classify as 'skill', others may feel differently.

KJ

Reply to
KJ

KJ,

Do you find that you are getting good usage of carry out in place of zero detection with natural?

For example, with unsigned, I can explicitly code the carry out by adding one bit to my decrement resource (variable Count17) as shown below. As a result, the zero detect is implemented as a single carry/borrow cell (one LUT) for any size of counter. If you do a test, make sure to use at least 16 bits so you can notice the difference.

signal EndDetect : std_logic ; signal Count16Reg : unsigned(15 downto 0) ; ...

process (...) variable count17 : unsigned(16 downto 0) ; begin ... Count17 := Count17 - 1 ; EndDetect

Reply to
Jim Lewis

Here's how I do it with natural types:

signal count : natural range 0 to 2**numbits - 1;

...

if count - 1 < 0 then do_end_of_count_stuff_here; else count

Reply to
Andy

Andy,

Which tools have you verified that the synthesis tools give you a good implementation?

Cheers, Jim

Reply to
Jim Lewis

Yes. For a related rollover example using unsigned, see the carry chain map for the "Clk Enabled Counters" example here:

formatting link

-- Mike Treseler

Reply to
Mike Treseler

Symplify, XST, and even the old Synopsys FC2 would handle it appropriately. I'm pretty sure Precision and Quartus handle it as well.

Oh yeah, I meant to say it works with n-bit rollovers (if count + 1 >

2**n-1 then...) for up counters... Mike knew what I meant!

Andy

Reply to
Andy

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.