RT Level Hardware Description with VHDL:Sequential Circuits
Sequential Circuits
As with any digital circuit, a sequential circuit can be described in VHDL by the use of gates, Boolean expressions, or behavioral constructs (e.g., process statements). Although gate level description allows a more detailed description of timing and delays, because of the complexity of clocking, and register and flip-flop controls, sequential circuits are usually described by process statements. In the next section we will first discuss some basic elements at the gate level and then represent coding styles for more complex sequential circuits.
Basic Memory Elements at the Gate Level
A clocked D-latch latches its input data when clock is active. The latch structure retains its value until the next active clock cycle. This element is the basis of all static memory elements.
Figure 87.19 shows a simple implementation of the D-latch that uses cross-coupled NOR gates, while the corresponding VHDL code is shown in Figure 87.20. Notice the use of buffer for q and q_b. This is due to the use of these signals on the right-hand side of signal assignments. These signals could have been declared as out and two signals could have done the job, but in this case two additional signal assignments would have been added to the code.
This code can be coded in another way using a simple conditional signal assignment as below: q <= d when c = ‘1’ else q;
Using two such statements with complementary clock values describes a master–slave flip-flop. As shown in Figure 87.21, qm is the master output and q the flip-flop output.
Memory Elements Using Procedural Statements
Although latches and flip-flops can be described in gate level by component instantiation and signal assignments, describing more complex register structures cannot be done this way. This section presents coding styles for describing latches and flip-flops using process statements. Later on, it will be shown that the same coding styles presented here can be used to describe memories with more complex control units as well as functional register structures such as counters and shift registers.
Latches
Figure 87.22 illustrates a D-latch described with a process statement. This process statement is sensitive to the latch clock and data input represented by c and d, respectively. The if statement used in the process statement puts the data input into q when the latch clock is active. This implies that any change on d while c is 1 can be transparently seen on the output. This behavior is referred to as transparency and it is how latches work.
D Flip-Flop
Different to latches, the data on D flip-flop’s input does not directly propagate to its output. This change will only have an affect on the specified edge of the clock. Consider Figure 87.23, which describes a positive-edge trigger D flip-flop. The process statement used is sensitive to changes on the clock input. Since the code describes a positive-edge flip-flop, it only transfers the data on the D-input to its output when clk has made a 0 to 1 transition. A process statement sensitive to the clk and an if statement that
determines a 0 to 1 transition on clk specifies the positive edge of clk. Similarly, a negative-edge trigger D flip-flop is created by changing the if statement to “if clk = ‘0’.”
Synchronous Control
The coding style presented for D flip-flops is general and can be easily expanded to describe many features found in flip-flops and memory structures. One of these features is having synchronous control for setting and resetting. The VHDL code of Figure 87.24, describes a D flip-flop with synchronous set and reset inputs.
The difference between this type of flip-flop and a simple D flip-flop is that on every positive edge of the clock, it first checks for the set and rest inputs and puts a 1 into the output if s is active and a 0 if r is active. Only when s and r are inactive the flip-flop places the D-input on its output. Note that the s input has been given a higher priority to r by first checking for s in the sequential process statement. The flip-flop structure corresponding to this description is shown in Figure 87.25.
Note that any other synchronous control can be added in the same way. For example, a clock enable input can be easily added by including another if statement in the else part of the last if statement before putting d into q.
Asynchronous Control
Consider the VHDL code of Figure 87.26 that describes a D flip-flop with asynchronous control. To have asynchronous control inputs we only need to add these signals to the process sensitivity list and change the ordering of if statement conditions. In the previous case when the process statement was only sensitive to clk, the flow of the process statement would only start if any change happened on the clk input. In other words, changes on control inputs did not have any effect on starting the flow of the process statement. In
this case however, by adding control signals to the sensitivity list, the process block flow can start by any event seen on these signals or the clk.
Registers, Shifters, and Counters
As mentioned previously, the coding styles presented for flip-flops can be extended to be used in other sequential circuits such as registers, shift registers, and counters.
Registers
Figure 87.27 shows the VHDL code for an 8-bit register with synchronous set and reset control. An 8-bit register is defined similar to a D flip-flop but for a bit-vector of eight elements. Assigning 1s (0s) to bits of q is done by an aggregate operation on the right-hand side of the assignment. This operation selects bits of the right-hand-side vector it is forming and associates values to these bits. The others keyword can be used in array aggregates to select all the indexes that have not been selected up to the appearance of others. A special case of this form, which is used in our example, is when no other indexes have been selected. In this case others selects all the indexes of the array.
Shift Registers
Consider Figure 87.28, which describes a 4-bit shift register with synchronous reset, right and left shift capability, and parallel loading.
Note that instead of having two variables q and q_t we could have defined q as buffer.
Counters
Figure 87.29 describes a 4-bit up-down counter with reset control input and parallel loading capability. The code for this counter is similar to the shift register described above. The only difference is that the
counter performs arithmetic addition or subtraction instead of shifting. The u_d input determines whether the counter counts up or down. Upon activation of the ld input on the positive edge of the clock, the value on d_in will be loaded into the counter. Again, definition of q as a buffer would have eliminated the use of variable t_q.
State Machine Coding
Finite-state machines, which are commonly used in the controller part of a digital system that has been partitioned into a data path and a controller, can be modeled in VHDL. This section shows coding styles used for Moore and Mealy state machines. The examples presented here are simple sequence detectors; however they present coding styles for coding more complex controllers.
Moore Detector
A Moore machine is a finite-state machine, which indicates an output signal for each state independent of circuit’s inputs.
Figure 87.30 shows the state diagram for a 101 Moore sequence detector. The machine looks for a sequence of 101 and when found, signals the output to become 1.
Figure 87.31 shows the VHDL code for this state diagram. The current state is represented by an enumeration type. This type has a value for each state; therefore, for detecting 101 this type should have
four values including init. Figure 87.31, shows an enumeration-type declaration that declares States as a set of four states including init, got1, got10, and got101. Type declarations take place in the declarative part of the architecture body. As another example of enumeration types, consider the bit type of the standard package that is an enumeration of ‘0’ and ‘1’.
The process statement, which is sensitive to clk, is in charge of state transitions and register clocking. Upon the positive edge of the clock, checked by “clk = ‘1’ and clk’event” the process statement checks
for the clr input. If clr is active then the next state becomes init by assigning init to current. Note that the value put into current in this pass gets checked in the next run of the process statement. On the other hand if the clr input is not active, the program flow reaches the case statement and takes one of the case alternatives according to current. A single conditional signal assignment is in charge of assigning values to z.
Mealy Detector
Finite-state machines can also be implemented as Mealy state machines whose output, unlike Moore state machines, is determined by the current state of the machine as well as the inputs of the circuit. Therefore the Mealy outputs are not fully synchronized with the clock input. Figure 87.32 shows the state diagram of a Mealy state machine that inspects a 101 sequence on its input. In this state diagram the outputs are determined by the edges coming out of the states.
Notice that we only have three states in this example, in contrast with the four states of the Moore implementation. Usually, there is an extra state in the Moore state machine since output ‘1’ needs to be associated with a state. The VHDL code for this machine is shown in Figure 87.33.
As shown the process statement is only responsible for the state transitions. The output is determined with the conditional signal assignment in the architecture body. Notice that overlapping sequences are allowed in both examples.
Huffman Coding Style
The Huffman model for a digital system characterizes it as an interconnection of a combinational and a register block. In VHDL, a Huffman model can be described using two process blocks, one describing the register part and the other for the combinational part. This is shown in Figure 87.34.
Figure 87.35 shows the VHDL code for the Moore sequence detector described before according to the Huffman model. This time instead of current, present state (p_state) and next state (n_state) have been used. The sequential part of the circuit is coded using a process statement with clr and clk in its sensitivity list. On the positive edge of the clk, p_state is either set to init in case of clr, or loaded with n_state.
The combinational block however uses a case statement in the process block to decide the next state. This case statement has case alternatives for init, got1, got10, and got101. In each case, based on inputs, ns and y are assigned values.
Memories
Memories are represented with user-defined types in VHDL. Figure 87.36 shows a memory declaration and its corresponding block diagram together with several valid memory operations. As said before, type
declarations take place in the declarative part of an architecture. Here, type memory is defined as an unconstrained array of 8-bit std_logic vectors. Then the mem signal is defined as a 1023-element array of memory elements.
A memory can be written into or read from with the use of signal assignments and indexing. A memory can be read by addressing it within its address range. A part of a word can be read directly from a memory using double indexing.
Comments
Post a Comment