6. Behavioural Design

What? Why? How?

When using behavioural level design it is often a good idea to try to describe the functionality you desire in a sentence. This can usually then be dissected into 'if', 'else', 'assign', and '<=' (take the value of) statements. For example, a synchronously resetting DType could be described as:

On the rising edge of the clock, if RESET is '1' then OUT takes the value of '0' else OUT takes the value of IN.

"On the rising edge of the clock" describes the sensitivity list. The "if RESET is '1' then" describes a conditional statement with two outcomes, and the remainder of the sentence describes how to deal with the two outcomes, with the "takes the value of" text denoting '<=' syntax.

Start Writing Behaviourally

Now we will try to make the same shift register as in the Gate Level section, but this time using behavioural level design principles. Just to recap, we are going to implement a serial in - parallel out shift register. Like the previous exercise, the clock will be controlled by a slide switch, and the input by a push button. Each of the wires that form part of the output 8-bit bus will be connected to one of the LEDs.

However, before we start writing sentences to turn into behavioural code, we must determine if there are any registers that will be controlled by this module. The answer is yes, as we are not using the D-Type module that was used for the gate level version. We have 8 registers, or a bus of registers [7:0] that store the current value of each of the D-Types instead.

We need a new Verilog module. Create it with the same interface as the previous "ShiftRegister" module, but call it something different, like "ShiftRegBehave". The first piece of code that is required is the register to store the state of our shift register between rising edges of the clock 'CLK'. This is with exactly the same form as the wire, in fact, the only difference is that 'wire' needs to be changed to 'reg'.

Now that we have defined the modules internal resources, we need to describe how the inputs will affect these resources (our array of registers "Dtypes").

If we think of these registers as an array of memory (will call it MEM[x]), with each DType being represented as a single element or cell of this array, we could represent the change in cell state as memory assignments. As this is a set of instructions it can be written in a sentence, albeit a long one.

At the rising edge of the 'CLK' signal,

MEM[7] takes the value of MEM[6],

MEM[6] takes the value of MEM[5],

MEM[5] takes the value of MEM[4],

MEM[4] takes the value of MEM[3],

MEM[3] takes the value of MEM[2],

MEM[2] takes the value of MEM[1],

MEM[1] takes the value of MEM[0],

MEM[0] takes the value of IN.

The output will always mirror the contents of the memory, so can therefore be written as:

OUT is always equal to MEM[7:0].

Now try and implement this as HDL in your module. The correct implementation is on the next page.