Você está na página 1de 13

Unit 4 Simulation and Hardware Modeling:

Model Simulation: Writing a test bench for a Half and a Full Adder. Hardware Modeling Examples: Modeling entity Interfaces, Modeling simple elements, Different styles of modeling, Modeling regular structures, Modeling delays, Modeling conditional operations, Modeling clock divider and a pulse counter. 4.1 Model Simulation: Before modeling a hardware, we require to identify which values are to be used during simulation. According to that the data type are defined for input and output ports in a model. If we are having a digital system with the specifications of the behavior of that system, e.g. we are having input signals, output signals and knowledge of the delays in generating the output signals, then the behavior of the circuit is described in terms of the occurrence of events and waveforms of signals. The VHDL simulator executes this model. This gives us many alternative designs and all are analyzed. The performance of each design is checked. Simulation detects functional errors in a design without actually constricting the circuit. If any errors are detected during simulation, then those can be corrected by modifying appropriate VHDL statements. Finally, the most correct design option is selected. Thus, design is finalized without actually fabricating the circuit. The process of simulation depends on the type of modeling used to describe a hardware. If a behavioral model is simulated, the library and package declaration is sufficient e.g. Library IEEE; Use ieee. Std_logic_1164. all; If structural model is to be simulated, it is useful to provide a package containing the component declarations for all components that reside in the library. 4.1.1 Test Bench: Test bench in VHDL can be considered as a virtual circuit tester which generates and applies stimulus to our design description. It is a model which verifies the correctness of a hardware model. There is advantage of writing a test bench in the same language as the unit under test: that is the designer does not need any specialized simulation tool or simulation language. The unit under test becomes a part of the test bench, and can be considered as an instance of an actual design. A test bench has three main purposes: 1. To generate stimulus for simulation. 2. To apply this stimulus to the entity under test and collect the output responses (waveform generation). 3. To compare output responses with expected values (output response monitoring). The general architecture of a test bench is shown in fig. 4.1

Fig. 4.1: Test Bench Architecture The syntax for Test Bench is shown below: Entity test_bench is End; architecture <Architecture_ name> of test_bench is component <component_name> port (port_name: mode data type); end component; Local signal declaration; Begin Statements; End <architecture_name>; Given below is the behavioral model code of a 4 bit counter with reset input: Library IEEE; Use ieee. Std_logic_1164. all; Use ieee. Std_logic_arith. all; Use ieee. Std_logic_unsigned. all; Entity test is Port ( Clk : in std_logic; Count : out std_logic_vector ( 3 downto 0); Reset : in std_logic); End test; Architecture behv of test is Signal c : std_logic_vector ( 3 downto 0):= (others => 0); -- initializing count to 0. Begin Count <= c; Process (clk, reset) Begin If (clkevent and clk = 1) then -- when count reaches 15 (its maximum) reset it to 0. If c = 1111 then c <= 0000; end if; c <= c +1; -- increment count at every positive edge of clk. End if;

If (reset = 1) then C <= (others => 0); End if; End process; End behv;

-- when reset=1 make count = 0. -- c = 0000

For the above code the testbench is given below: Library IEEE; Use ieee. Std_logic_1164. all; Use ieee. Std_logic_unsigned. all; -- In entity declaration for testbench we dont declare any ports here. Entity test_bench is End test_bench; Architecture behv1 of test_bench is -- Component declaration for design under test. Component test -- test is the name of the module to be tested. -- Inputs and outputs are same as the module itself

port ( clk : in std_logic; count : out std_logic_vector ( 3 downto 0); reset : in std_logic); end component; -- declare inputs and initialize them signal clk : std_logic := 0; signal reset : std_logic := 0; -- declare outputs and initialize them signal count : std_logic_vector(3 downto 0); -- Clock period definitions constant clk_period : time := 1 ns; BEGIN -- Instantiate the Unit Under Test (UUT) uut: test PORT MAP ( clk => clk, count => count; reset => reset ); -- Clock process definitions( clock with 50% duty cycle is generated here. clk_process :process begin clk <= '0'; wait for clk_period/2; --for 0.5 ns signal is '0'. clk <= '1';

wait for clk_period/2; --for next 0.5 ns signal is '1'. end process; -- Stimulus process stim_proc: process begin wait for 7 ns; reset <='1'; wait for 3 ns; reset <='0'; wait for 17 ns; reset <= '1'; wait for 1 ns; reset <= '0'; wait; end process; END behv; 4.1.1.1 Waveform Generation: Waveforms are typically required in two types: Repetitive Pattern Sequential set of values. (a) Repetitive patterns can be created with a constant on-off delay using concurrent signal assignment statements. This can be achieved in two ways either by defining delay in approximate time duration e.g. A <= not A after 10 ns; Or by creating clock using a process e.g. Process Constant offp : Time := 7ns; Constant onp : Time := 10ns; Begin Wait for offp; D <= 1; -- D is assumed to be a signal of type bit Wait for onp; D <= 0; End Process; In the above two examples, simulation would execute until Time = TimeHigh. We can avoid this by assert statement in the process. Example: Assert N <= 100ns; Report Simulation completed Severity Warning;

In this example, assertion would fail when simulation time exceeds 100ns, and the simulation stops. We can also stop a process from executing by using wait statement of the format: wait; Example: If N> 100 ns then wait; end if; (b) Sequential Set of Values: This method is used basically to monitor the output response of an entity. In this, we apply a vector, sample the output after a specific time and then to verify to make sure that the output response matches the expected values. 4.2 Hardware Modeling Examples: As we have discussed earlier, in VHDL we can model a hardware using three styles of modeling i.e. o Behavioral Style of Modeling o DataFlow Style of Modeling o Structural Style of Modeling 4.2.1 Modeling Entity Interfaces: Entity interface ports are defined in the entity declaration part. The syntax for entity declaration is entity <entity_name> is port (signal name1, signal name2 : mode data type;

. . );
end <entity_name>; Port specifies the name of the signals that interact with the external environment of the entity. Mode and data type defines the basic working of the signals. Example: Entity q1 is Port (A, B :in BIT; C, D : out BIT); End q1; In the above example, q1 is the name of the entity. A, B, C, D are the signal names. Signals A and B are of type BIT and in IN mode i.e. the values assigned by the user are input to the system and can accept values of the type BIT i.e. 0 or 1. 4.2.2 Modeling Simple Elements: In this section, we will discuss the behavior of the simple elements. Some hardware examples are given below: Example 1: Behavior of OR gate:

Solution: Library IEEE; Use IEEE.STD_LOGIC_1164.all; Entity ORG is End ORG; Architecture ORG_1 of ORG Signal A, B, C : STD_LOGIC; Begin C <= A OR B; End ORG_1; The hardware represented by the above model is shown in fig. 4.2:

Fig. 4.2 Example 2: Behavior of Combinational Circuit shown in fig. 4.3:

Fig. 4.3 Solution: Library IEEE; Use IEEE.STD_LOGIC_1164.all; Entity C_C is End C_C; Architecture C_C1 of C_C is Signal A, B, C, D, E : STD_LOGIC; Begin E <= A OR B; D <= E OR C; END C_C1; 4.2.3 Different Styles of Modeling: In VHDL we can design a circuit or a hardware in three different styles i.e. there are three different modeling styles provided by the language: Dataflow, Behavioral, Structural. For all the three styles of modeling entity declaration is the same. We consider the circuit shown in fig. 4.4

Fig 4.4 Entity SLF is Port ( A, B, C : in bit; F : out bit); end SLF; Architecture Body for the three styles of Modeling: 1) Dataflow Style of Modeling: Architecture SLF1 of SLF is Begin F <= (A and B) or (not B and C); End SLF1; 2) Behavioral Style of Modeling: Architecture SLF1 of SLF is Signal E, G, H : BIT; Begin Process ( A, B) E <= A and B; H <= not B; G <= H and C; F <= E or G; End Process; End SLF1; 3) Structural Style of Modeling: Architecture SLF1 of SLF is Component AND1 Port (A1, B1 : in BIT; E1 : out BIT) ;

End Component; Component NOT1 Port ( B2 : in BIT; C0 : out BIT); End Component; Component OR1 Port ( E1, G1 : in BIT; F1 : out BIT); End component; Signal E, G, H : BIT; Begin X0 : AND1 portmap (A, B, E); X1 : NOT1 portmap ( B, H ); X2 : AND1 portmap ( H, C); X3 : OR1 portmap ( E, G, F); End SLF1; 4.2.4 Modeling Regular Structures: In this section, we will discuss the modeling of any regular structure. Let us assume to construct a 10 deep, 8 bit stack using 8 bit registers. The stack will have a input port, an output port and a control signal which specifies whether to push or to pop the data. In this case we are ignoring overflow and underflow conditions. Now, we have ten 8-bit registers in a stack. In a push operation, input to each register is from the top register while in pop operation it is from bottom register. The model is given below. Library IEEE; Use ieee.STD_LOGIC_1164.all; Entity S0 is Port (Din : in STD_LOGIC_VECTOR (0 to 7); Dout : out STD_LOGIC_VECTOR (0 to 7); Clk, stk, Ctrl : in STD_LOGIC); End S0; Architecture S00 of S0 is Type stk0 is array (1 to 10) of STD_LOGIC_VECTOR (0 to 7); Signal regin : STD_LOGIC_VECTOR (0 to 7); Signal data : stk0; Component reg Port (Din0 : in STD_LOGIC_VECTOR (0 to 7); Dout0 : out STD_LOGIC_VECTOR (0 to 7); Clk0 : in STD_LOGIC); End component; Begin R1 : for N in 1 to 10 generate -- 10 is the top and 1 is bottom of the stack R2 : if N = 10 generate

Regin <= Din when stk = '1' Else data (N-1); End generate R2; R3 : if N>1 and N<10 generate Regin <= data (N +1) when stk = 1 Else data (N-1); End generate R3; R4 : if N = 1 generate Regin <= data (N+1) when stk = 1 Else (others => U);

-- Push -- Pop

End generate R4; FF0 : reg portmap (regin, data(N), Clk); End generate R1; Dout0 <= data(10); -- Output is connected to top of stack End S00; In this model, when the variable N =1 the stack is being popped, the input to the bottommost register is U. When N=10, the input to the top- most register is the input to the stack Din. The output of the top-most register is the output of the stack. . 4.2.5 Modeling Delays: VHDL provides two types of delays to model a hardware: Inertial Delay and Transport Delay. Inertial Delay is default in VHDL while transport delay is used to model wire delays. If no delay is specified in the model, then it is assumed to be inertial delay. Inertial delay provides a behavior similar to the actual device. Inertial delay specifications may contain a reject clause. This clause can be used to specify the minimum impulse width that will be propagated, regardless of the switching time specified. If the delay mechanism is not specified then by default it is inertial. If a narrow pulse having width less than the delay time appears at the input then the pulse is not passed to the output i.e. if the input is not stable for the specified limit, no output change occurs. The limit or duration for which the input must be stable is called as the pulse rejection limit. The inertial delay model is shown below: Library IEEE; Use work. Std_logic_1164.all; Entity iner_ex is Port ( A, B : in std_logic; C : out std_logic); End iner_ex; Architecture arch of iner_ex is Begin C <= A AND B after 10ns; End arch;

Transport delay is specified using the reserved word transport and is characteristic for transmission line. New signal value is assigned with specified delay independently from the width of the impulse in the waveform. Unlike Inertial delay, transport delay repeats the input waveform after the specified delay irrespective of the pulse width. It is a pure propagation delay. The keyword transport must be used in the signal assignment statement to represent transport delay. This is the ideal type of delay model as the spikes are also propagated to the output which are ignored in inertial delay. The transport delay model is given below: Library IEEE; Use work. Std_logic_1164.all; Entity iner_ex is Port ( A, B : in std_logic; C : out std_logic); End iner_ex; Architecture arch of iner_ex is Begin C <= transport (A AND B) after 10ns; End arch; The above example is similar to inertial delay example except for the keyword transport in the signal 4.2.6 Modeling Conditional Operators: Conditional operations can be modeled using either a selected signal assignment statement or a conditional signal assignment statement. We consider the example of a Multiplexer Library ieee; Use ieee.std_logic_1164.all; Use ieee.std_logic_arith.all; Entity Mux1 is Port ( I0, I1, I2, I3: in bit; S0, S1 : in bit_vector (0 to 1); Y : out bit); end Mux1; Architecture Mux_beh of Mux1 is Begin Process (I0, I1, I2, I3, S) Begin Case s is When 00 => Y <= I0; When 01 => Y <= I1; When 10 => Y <= I2; When 11 => Y <= I3; End Case; End process; End Mux_beh;

In the above example, the sensitivity list elements are the inputs and the select lines. The value of the select lines are first determined and based on this value, a case statement selects the appropriate input that is to be assigned to the output. 4.2.7 Modeling Clock Divider and a Pulse Counter: The model of clock divider as well as the pulse counter is given below: 4.2.7.1 Clock Divider: A generic model of a divide- by-2*N clock generator is given below: Library ieee; Use IEEE. STD_LOGIC_1164.all; Entity Clk_div is Genric (K : positive); Port (Clk, rst : in std_logic; Clk_d : buffer std_logic); End Clk_div; Architecture behv of Clk_div is Begin process (Clk, rst) Variable cnt : Natural; Begin If rst = 0 then cnt := 0; Clk_d <= 0; Elsif Clkevent and Clk = 1 then Cnt := Cnt +1; If Cnt = K then Clk_d <= not Clk_d; Cnt := 0; End if; End if; End process; End behv; In the above modeling, as long as rst = 0, the clock divider output Clk_d is 0. When rst = 1, the counter starts counting from the next rising clock edge. When all the K edges have been detected, the clock divider output Clk_d is inverted and the counter is reset to 0 and the cycle repeats. The waveform for a divide-by-6 clock divider is shown in fig. 4.5

Fig 4.5 4.2.7.2 Pulse Counter: A pulse counter is a circuit that counts the number of clock pulses contained within a signal. The model for pulse counter is given below: Library ieee; Use ieee. STD_LOGIC_1164. all; Entity p_cntr is Generic (max_cnt : Natural := 45); --max_cnt is the maximum count --limit of the counter Port (Clk, sig : in STD_LOGIC; Cnt : out Integer range 0 to max_cnt-1; Ovrfl : out Boolean); -- Ovrfl represents overflow flag End p_cntr; Architecture behv of _cntr is Begin Process (Clk, sig) Variable Cnt1: Natural; Variable Cnt2 : Boolean; Begin If sigevent then If sig = 1 then -- Reset on rising edge ovrfl <= FALSE; Cnt2 := TRUE; Cnt1 := 0; Elsif sig = 0 then Cnt2 := FALSE; End if; Elsif Clkevent and Clk = 1 then -- Rising edge of the clock if Cnt2 then -- Cnt2 represents start of counting Cnt1 := Cnt1 + 1; -- Counting is incremented by 1 if Cnt1 > max_cnt then Cnt1 := 0;

Ovrfl <= TRUE; Cnt2 := FALSE; End if; End if; End if; Cnt <= Cnt1; End process; End behv; In the above code, if the count Cnt1 exceeds the signal limit max_cnt, an overflow flag Ovrfl is set. The waveform is shown in fig. 4.6.

Fig 4.6 After the signal sig goes LOW, the counter value is retained until the another rising edge occurs on sig.

Você também pode gostar