Summary, so far...
Before we go any further let's summarise where we have got to...
- We know how to create a component in VHDL
- We know how to join components together
Joining components together is one method of design using VHDL. It's the bottom-up approach. There's nothing wrong with joining components together to create a design hierarchy, but using it as your design approach exclusively can restrict your productivity even though it is possible to create any design you could wish for using VHDL in this manner. Let's step back a moment and consider how the design of something as simple as a MUX_2 is being implemented; not at a hardware level but at a conceptual level. We'll change the MUX_2 so that it has an inverting data path:
signal SELB, FB: STD_LOGIC; begin G1: INV port map (SEL, SELB); G2: AOI port map (SEL, A, SELB, B, FB); G3: INV port map (FB, F);
Well, that's three components. The largest port list has only 5 elements. There's only two levels of hierarchy. The target technology has to have cells called AOI and INV. Suppose the widths of the A, B inputs have to be changed?
What about a 100k gate ASIC? With multiple levels of hierarchy. Suppose it has to be technology independent, too. Creating large designs in this manner is very time-consuming. It is error-prone (it's just too easy to connect the wrong signal to a port). It is awkward to make changes to the design as a whole (change all the busses in a design by 1 bit, for example to add parity). This approach to creating functionality is often referred to as a structural coding style.
Adopting a structural design approach, we first have to decide what we want to do (switch between two inputs) and secondly how to implement it (using components). So, while joining components together has its place, we really ought to move on to a better low-level design approach. Instead of determing the functionality and then implementing it, we're going to describe the functionality and leave it at that. We're not going to worry about implementation. Well, ultimately we will concern ourselves with implementation but from a coding point of view, let's get the functionality or behaviour out of the way first.
At a conceptual level we can specify what we want the design to do using a behavioural coding style. Using the structural approach, we have to describe explicitly how the design is to be implemented. Thus a structural approach implies an extra step in the design process.
So, how do we implement a behavioural coding style? Well, this can be achieved by writing VHDL code as though we were writing software rather than describing hardware. We can take our VHDL coding capabilities closer to VHDL programming, closer to writing software rather than describing hardware. By writing software rather than describing hardware, we can concentrate on what a design does rather than how it does it. We can concern ourselves with functionality rather than implementation. In the same way that mathematicians look to abstract a concept to make a problem easier to solve and provide more flexible solutions, we can abstract our designs from VHDL hardware descriptions to VHDL software functions. However, a software function will still at some point become a hardware description. We can bridge the gap from software function to hardware description using synthesis.
With the behavioural approach to design, we still have to decide what we want to do, but that's it. We can use synthesis tools to decide how to implement the functionality we have (behaviourally) specified. There are still two steps in creating a netlist that meets our design goals, it's just that with a behavioural approach we use design automation to complete the second (implementation) step. Hopefully, this can save us time because we as engineers only have to do one job instead of two. Using a software-oriented design approach we can reduce the number of design steps.
Next, we'll look at how to code up the MUX_2 circuit in a software-oriented manner using VHDL processes.
Your e-mail comments are welcome - send email