|
VHDL Tutorial |
Behavioral Descriptions in VHDL | ||
|
Introduction Fundamental concepts Modelling concepts Elements of behaviour Elements of structure Analysis elaboration Lexical elements Identifiers Numbers Characters and strings Syntax descriptions Constants and variables Scalar type Integer types Floating point types Time type Enumeration types Character types Boolean type Bits type Standard logic Sequential statements Case statements Loop and exit statements Assertion statements Array types & array operations Architecture bodies Entity declarations Behavioral descriptions Wait statements Delta delays Process statements Conditional signal assignment Selected signal assigment Structural descriptions Library and library clauses Procedures Procedure parameters Signal parameters Default values Unconstrained array parameter Functions Package declarations and bodies Subprograms in package Use clauses Resolved signals and subtypes Resolved signals and ports Parameterizing behavior Parameterizing structure |
Behavioral Descriptions
At the most fundamental level, the behavior of a module is described by signal assign- ment statements within processes. We can think of a process as the basic unit of be- havioral description. A process is executed in response to changes of values of signals and uses the present values of signals it reads to determine new values for other sig- nals. A signal assignment is a sequential statement and thus can only appear within a process. In this section, we look in detail at the interaction between signals and processes.
Want To have highly paid VLSI jobs ?? then you may contact at
Contact : webmaster@freehost7com
Signal Assignment
In all of the examples we have looked at so far, we have used a simple form of signal assignment statement. Each assignment just provides a new value for a signal. What we have not yet addressed is the issue of timing: when does the signal take on the new value? This is fundamental to modeling hardware, in which events occur over time. First, let us look at the syntax for a basic signal assignment statement in a pro- cess:
signal_assignment_statement ⇐ name <= ( value_expression [ after time_expression ] ) { , … } ;
The syntax rule tells us that we can specify one or more expressions, each with an optional delay time. It is these delay times in a signal assignment that allow us to specify when the new value should be applied. For example, consider the following assignment:
y <= not or_a_b after 5 ns;
This specifies that the signal y is to take on the new value at a time 5 ns later than that at which the statement executes. Thus, if the above assignment is executed at time 250 ns, and or_a_b has the value ‘1’ at that time, then the signal y will take on the value ‘0’ at time 255 ns. Note that the statement itself executes in zero modeled time. The time dimension referred to when the model is executed is simulation time, that is, the time in which the circuit being modeled is deemed to operate. We measure simulation time starting from zero at the start of execution and increasing in discrete steps as events occur in the model. A simulator must have a simulation time clock, and when a signal assignment statement is executed, the delay specified is added to the current simulation time to determine when the new value is to be applied to the signal. We say that the signal assignment schedules a transaction for the signal, where the transaction consists of the new value and the simulation time at which it is to be applied. When simulation time advances to the time at which a transaction is scheduled, the signal is updated with the new value. We say that the signal is active during that simulation cycle. If the new value is not equal to the old value it replaces on a signal, we say an event occurs on the signal. The importance of this distinction is that processes respond to events on signals, not to transactions. The syntax rules for signal assignments show that we can schedule a number of transactions for a signal, to be applied after different delays. For example, a clock driver process might execute the following assignment to generate the next two edges of a clock signal (assuming T_pw is a constant that represents the clock pulse width):
clk <= '1' after T_pw, '0' after 2*T_pw;
If this statement is executed at simulation time 50 ns and T_pw has the value 10 ns, one transaction is scheduled for time 60 ns to set clk to ‘1’, and a second trans- action is scheduled for time 70 ns to set clk to ‘0’. If we assume that clk has the value ‘0’ when the assignment is executed, both transactions produce events on clk.
We can write a process that models a two-input multiplexer as shown in Figure 4-1. The value of the sel port is used to select which signal assignment to execute to determine the output value.
mux : process (a, b, sel) is begin case sel is when '0' => z <= a after prop_delay; when '1' => z <= b after prop_delay; end case; end process mux; We say that a process defines a driver for a signal if and only if it contains at least one signal assignment statement for the signal. If a process contains signal assignment statements for several signals, it defines drivers for each of those signals. A driver is a source for a signal in that it provides values to be applied to the signal. An important rule to remember is that for normal signals, there may only be one source. This means that we cannot write two different processes each containing signal assignment state- ments for the one signal. If we want to model such things as buses or wired-or sig- nals, we must use a special kind of signal called a resolved signal, which we will discuss later. Signal Attributes
VHDL provides a number of attributes for signals to find information about their his- tory of transactions and events. Given a signal S, and a value T of type time, VHDL defines the following attributes:
S'delayed(T) A signal that takes on the same values as S but is delayed by time T. S'event True if there is an event on S in the current simulation cycle, false otherwise.
S'last_event The time interval since the last event on S.
S'last_value The value of S just before the last event on S.
These attributes are often used in checking the timing behavior within a model. For example, we can verify that a signal d meets a minimum setup time requirement of Tsu before a rising edge on a clock clk of type std_ulogic as follows:
if clk'event and (clk = '1' or clk = 'H') and (clk'last_value = '0' or clk'last_value = 'L') then assert d'last_event >= Tsu report "Timing error: d changed within setup time of clk"; end if;
We can test for the rising edge of a clock signal to model an edge-triggered flipflop. The flipflop loads the value of its D input on a rising edge of clk, but asynchronously clears the outputs whenever clr is ‘1’. The entity declaration and a behavioral architecture body are shown in Figure 4-2.
entity edge_triggered_Dff is port (D : in bit; clk : in bit; clr : in bit; Q : out bit ); end entity edge_triggered_Dff; –– ––– –––– ––– –––– –––– ––– –––– ––– –––– ––– –––– –––– ––– –––– architecture behavioral of edge_triggered_Dff is begin state_change : process (clk, clr) is begin if clr = '1' then Q <= '0' after 2 ns; elsif clk'event and clk = '1' then Q <= D after 2 ns; end if; end process state_change;
An entity and architecture body for an edge-triggered flipflop, using the 'event attribute to check for
|