Testbench and simulation
Bahavioral simulation
Test bench for the component ProcessingUnit
This test bench applies a cyclic sensor signal to the processing unit, generated in three steps. Clock_Generator provides HIGH pulses with a period adjusted by the generic parameter ClockPeriod on SystemClock_1. The pulse duty ratio of the output signal, as defined by the subsequent formula, is v = 0.5.
Figure 44: Output waveform of the component Clock_Generator
ImpulsGen generates a pulse with a width of tp = 10 ms. This signal must still be inverted, since ReedContact_In is a LOW active signal. By changing the parameter ClockPeriod, any speed value can therefore be simulated.
Figure 45: Signal transformation by the component ImpulsGen
Initially PerimeterImpulsGen generates pulses on IncWheel to test the wheel circumference setting. ProcessingUnit_tester provides an initial system reset on the line Reset.
Figure 46: Test bench for ProcessingUnit
Furthermore it controls the DisplayMode in order to determine the actual active display mode, New_DisplayMode, indicating a change of the display mode and Reset_Computer for resetting the measured values. The System_Clock_Generator generates a 3.2768 Mhz system clock. For this the generic parameter ClockPeriod is assigned to the corresponding time period.
-- University of Applied Sciences / Munich
-- Federal Technological Education Center / Rio de Janeiro
-- =======================================================
-- = Project : Bicycle computer in VHDL =
-- = File : processingunit_tb_struct.vhd =
-- = Notes : BikeCom.ProcessingUnit_tb =
-- =======================================================
-- = Datum : 08.08.2001 =
-- = Design : Joachim Reiss =
-- = Revision: 001 =
-- =======================================================
--
--
--
-- VHDL Entity BikeCom.ProcessingUnit_tb.symbol
--
ENTITY ProcessingUnit_tb IS
END ProcessingUnit_tb ;
--
-- VHDL Architecture BikeCom.ProcessingUnit_tb.struct
--
LIBRARY ieee ;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;
LIBRARY BikeCom ;
USE BikeCom.data.ALL;
ARCHITECTURE struct OF ProcessingUnit_tb IS
-- Internal signal declarations
SIGNAL DisplayMode : AllModes;
SIGNAL ImpulsOut : std_logic;
SIGNAL LCD_BCD : std_logic_vector(19 DOWNTO 0);
SIGNAL New_DisplayMode : std_logic;
SIGNAL Print_BCD : std_logic;
SIGNAL ReedContact_In : std_logic;
SIGNAL Reset : std_logic;
SIGNAL Reset_Computer : std_logic;
SIGNAL SystemClock : std_logic;
SIGNAL SystemClock_1 : std_logic;
SIGNAL WheelPerimeterAdjust : std_logic;
-- Component Declarations
COMPONENT Clock_Generator
GENERIC (
ClkPeriod : Time := 10 ms
);
PORT (
ResetClock : IN std_logic ;
Clock : OUT std_logic
);
END COMPONENT;
COMPONENT ImpulsGen
PORT (
FallingEdge_In : IN std_logic ;
Reset : IN std_logic ;
Systemclock : IN std_logic ;
ImpulsOut : OUT std_logic
);
END COMPONENT;
COMPONENT PerimeterImpulsGen
PORT (
WheelPerimeterAdjust : OUT std_logic
);
END COMPONENT;
COMPONENT ProcessingUnit
GENERIC (
CompareValue_KmActual : std_logic_vector(16 DOWNTO 0) := "00000001111101000";
CompareValue_KmTotal : std_logic_vector(16 DOWNTO 0) := "11000011010100000";
StopOnTimeOut : std_logic_vector(13 DOWNTO 0) := "11101001001000"
);
PORT (
Clock : IN std_logic ;
DisplayMode : IN AllModes ;
Inc_Wheel : IN std_logic ;
New_DisplayMode : IN std_logic ;
Reed : IN std_logic ;
Reset : IN std_logic ;
Reset_Computer : IN std_logic ;
LCD_BCD : OUT std_logic_vector (19 DOWNTO 0);
Print_BCD : OUT std_logic
);
END COMPONENT;
COMPONENT ProcessingUnit_tester
PORT (
LCD_BCD : IN std_logic_vector (19 DOWNTO 0);
Print_BCD : IN std_logic ;
DisplayMode : OUT AllModes ;
New_DisplayMode : OUT std_logic ;
Reset : OUT std_logic ;
Reset_Computer : OUT std_logic
);
END COMPONENT;
COMPONENT System_Clock_Generator
GENERIC (
ClockPeriod : Time := 305175 ps
);
PORT (
SystemClock : OUT std_logic
);
END COMPONENT;
-- Optional embedded configurations
-- pragma synthesis_off
FOR ALL : Clock_Generator USE ENTITY BikeCom.Clock_Generator;
FOR ALL : ImpulsGen USE ENTITY BikeCom_Reiss.ImpulsGen;
FOR ALL : PerimeterImpulsGen USE ENTITY BikeCom.PerimeterImpulsGen;
FOR ALL : ProcessingUnit USE ENTITY BikeCom.ProcessingUnit;
FOR ALL : ProcessingUnit_tester USE ENTITY BikeCom.ProcessingUnit_tester;
FOR ALL : System_Clock_Generator USE ENTITY BikeCom.System_Clock_Generator;
-- pragma synthesis_on
BEGIN
-- Architecture concurrent statements
-- eb1 1
ReedContact_In <= NOT (ImpulsOut);
-- Instance port mappings.
I3 : Clock_Generator
GENERIC MAP (
ClkPeriod => 43720 us
)
PORT MAP (
ResetClock => Reset,
Clock => SystemClock_1
);
I4 : ImpulsGen
PORT MAP (
FallingEdge_In => SystemClock_1,
Reset => Reset,
Systemclock => SystemClock,
ImpulsOut => ImpulsOut
);
I5 : PerimeterImpulsGen
PORT MAP (
WheelPerimeterAdjust => WheelPerimeterAdjust
);
I0 : ProcessingUnit
GENERIC MAP (
CompareValue_KmActual => "00000001111101000",
CompareValue_KmTotal => "11000011010100000",
StopOnTimeOut => "11101001001000"
)
PORT MAP (
Clock => SystemClock,
DisplayMode => DisplayMode,
Inc_Wheel => WheelPerimeterAdjust,
New_DisplayMode => New_DisplayMode,
Reed => ReedContact_In,
Reset => Reset,
Reset_Computer => Reset_Computer,
LCD_BCD => LCD_BCD,
Print_BCD => Print_BCD
);
I1 : ProcessingUnit_tester
PORT MAP (
LCD_BCD => LCD_BCD,
Print_BCD => Print_BCD,
DisplayMode => DisplayMode,
New_DisplayMode => New_DisplayMode,
Reset => Reset,
Reset_Computer => Reset_Computer
);
I2 : System_Clock_Generator
GENERIC MAP (
ClockPeriod => 305175 ps
)
PORT MAP (
SystemClock => SystemClock
);
END struct;
Clock generator
-- University of Applied Sciences / Munich
-- Federal Technological Education Center / Rio de Janeiro
-- =======================================================
-- = Project : Bicycle computer in VHDL =
-- = File : system_clock_generator_flow.vhd =
-- = Notes : BikeCom.System_Clock_Generator =
-- =======================================================
-- = Datum : 07.08.2001 =
-- = Design : Joachim Reiss =
-- = Revision: 001 =
-- =======================================================
--
--
--
-- VHDL Entity BikeCom.System_Clock_Generator.symbol
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY System_Clock_Generator IS
GENERIC(
ClockPeriod : Time := 305175 ps
);
PORT(
SystemClock : OUT std_logic
);
-- Declarations
END System_Clock_Generator ;
--
-- VHDL Architecture BikeCom.System_Clock_Generator.flow
--
ARCHITECTURE flow OF System_Clock_Generator IS
-- Architecture declarations
CONSTANT sys_clk_prd : time := ClockPeriod;
SIGNAL sys_clk_tmp : std_logic := '0';
BEGIN
---------------------------------------------------------------------------
process0 : PROCESS (sys_clk_tmp)
---------------------------------------------------------------------------
BEGIN
sys_clk_tmp <= NOT sys_clk_tmp AFTER sys_clk_prd / 2;
SystemClock <= sys_clk_tmp;
END PROCESS process0;
END flow;
Resetable clock generator
-- University of Applied Sciences / Munich
-- Federal Technological Education Center / Rio de Janeiro
-- =======================================================
-- = Project : Bicycle computer in VHDL =
-- = File : clock_generator_flow.vhd =
-- = Notes : BikeCom.Clock_Generator =
-- =======================================================
-- = Datum : 08.08.2001 =
-- = Design : Joachim Reiss =
-- = Revision: 001 =
-- =======================================================
--
--
--
-- VHDL Entity BikeCom.Clock_Generator.symbol
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY Clock_Generator IS
GENERIC(
ClkPeriod : Time := 10 ms
);
PORT(
ResetClock : IN std_logic ;
Clock : OUT std_logic
);
-- Declarations
END Clock_Generator ;
--
-- VHDL Architecture BikeCom.Clock_Generator.flow
--
ARCHITECTURE flow OF Clock_Generator IS
-- Architecture declarations
SIGNAL clk_tmp : std_logic := '0';
BEGIN
---------------------------------------------------------------------------
process0 : PROCESS (ResetClock, clk_tmp)
---------------------------------------------------------------------------
BEGIN
IF Falling_Edge (ResetClock) THEN
clk_tmp <= '1';
Clock <= clk_tmp;
END IF;
clk_tmp <= NOT clk_tmp AFTER ClkPeriod;
Clock <= clk_tmp;
END PROCESS process0;
END flow;
Pulse generator
The generation of pulses triggered by synchronous input signal requires more complex processing. The component consists of a state machine, that detects falling edges of the input signal FallingEdge_In and monitors all other internal signals including that of the timer component TimeOut.
Figure 49: Block diagram of the component ImpulsGen
An incoming pulse on FallingEdge_In forces the state machine to initialize the counter TimeOut with InitValue, specified by embedded block eb2. The defined value is not the value transferred into the internal counter of the component, but determines the time in steps of 10 ms, until CarryOut signals that the down counter has run into underflow. ImpulsOut takes on the level HIGH. Now TimeOut counts down the internal register and provides a pulse on CarryOut, as soos as the counter has underflowed. After this, ImpulsOut returns to LOW level.
-- University of Applied Sciences / Munich
-- Federal Technological Education Center / Rio de Janeiro
-- =======================================================
-- = Project : Bicycle computer in VHDL =
-- = File : impulsgen_struct.vhd =
-- = Notes : BikeCom.ImpulsGen =
-- =======================================================
-- = Datum : 08.08.2001 =
-- = Design : Joachim Reiss =
-- = Revision: 001 =
-- =======================================================
--
--
--
-- VHDL Entity BikeCom.ImpulsGen.symbol
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY ImpulsGen IS
PORT(
FallingEdge_In : IN std_logic ;
Reset : IN std_logic ;
Systemclock : IN std_logic ;
ImpulsOut : OUT std_logic
);
-- Declarations
END ImpulsGen ;
--
-- VHDL Architecture BikeCom.ImpulsGen.struct
--
LIBRARY BikeCom_Reiss;
ARCHITECTURE struct OF ImpulsGen IS
-- Internal signal declarations
SIGNAL CarryOut : std_logic;
SIGNAL EnCnt : std_logic;
SIGNAL InitValue : std_logic_vector(13 DOWNTO 0);
SIGNAL LoadCnt : std_logic;
-- Component Declarations
COMPONENT ImpulsGen_StateMachine
PORT (
CarryOut : IN std_logic ;
FallingEdge_In : IN std_logic ;
Reset : IN std_logic ;
Systemclock : IN std_logic ;
ImpulsOut : OUT std_logic ;
LoadCnt : OUT std_logic
);
END COMPONENT;
COMPONENT TimeOut
PORT (
Systemclock : IN std_logic ;
EnCnt : IN std_logic ;
InitValue : IN std_logic_vector (13 DOWNTO 0);
Reset : IN std_logic ;
CarryOut : OUT std_logic ;
CountOut : OUT std_logic_vector (13 DOWNTO 0);
LoadCnt : IN std_logic
);
END COMPONENT;
-- Optional embedded configurations
-- pragma synthesis_off
FOR ALL : ImpulsGen_StateMachine USE ENTITY BikeCom.ImpulsGen_StateMachine;
FOR ALL : TimeOut USE ENTITY BikeCom.TimeOut;
-- pragma synthesis_on
BEGIN
-- Architecture concurrent statements
-- eb1 1
EnCnt <= '1';
-- eb2 2
InitValue <= "00000000000001";
-- Instance port mappings.
I1 : ImpulsGen_StateMachine
PORT MAP (
CarryOut => CarryOut,
FallingEdge_In => FallingEdge_In,
Reset => Reset,
Systemclock => Systemclock,
ImpulsOut => ImpulsOut,
LoadCnt => LoadCnt
);
I0 : TimeOut
PORT MAP (
Systemclock => Systemclock,
EnCnt => EnCnt,
InitValue => InitValue,
Reset => Reset,
CarryOut => CarryOut,
CountOut => OPEN,
LoadCnt => LoadCnt
);
END struct;
The component ImpulsGen_StateMachine
The counter of TimeOut determines the width of the pulses on line ImpulsOut. Monitoring of this counter and the low active input line FallingEdge_In is by means of this state machine. The initial state WaitRisingEdge, or rather after one clock cycle Trigger_WaitRisingEdge, is used to detect transitions of FallingEdge_In from HIGH to LOW. In this case the state machine moves to the state Impuls, where it sets the output line ImpulsOut to HIGH and restarts the down counter TimeOut by HIGH level on LoadCnt. The state WaitTimeOut is inserted to detect a rising transition of CarryOut, an indication of counter underflow. LoadCnt is reset to zero. After this, the state machine returns to the state WaitRisingEdge, where all output signals take on LOW level.
Figure 50: State diagram of the component ImpulsGen_StateMachine
-- University of Applied Sciences / Munich
-- Federal Technological Education Center / Rio de Janeiro
-- =======================================================
-- = Project : Bicycle computer in VHDL =
-- = File : impulsgen_statemachine_fsm.vhd =
-- = Notes : BikeCom.ImpulsGen_StateMachine =
-- =======================================================
-- = Datum : 08.08.2001 =
-- = Design : Joachim Reiss =
-- = Revision: 001 =
-- =======================================================
--
--
--
-- VHDL Entity BikeCom.ImpulsGen_StateMachine.interface
--
LIBRARY ieee ;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
ENTITY ImpulsGen_StateMachine IS
PORT(
CarryOut : IN std_logic ;
FallingEdge_In : IN std_logic ;
Reset : IN std_logic ;
Systemclock : IN std_logic ;
ImpulsOut : OUT std_logic ;
LoadCnt : OUT std_logic
);
-- Declarations
END ImpulsGen_StateMachine ;
--
-- VHDL Architecture BikeCom.ImpulsGen_StateMachine.fsm
--
ARCHITECTURE fsm OF ImpulsGen_StateMachine IS
-- Architecture Declarations
TYPE STATE_TYPE IS (
WaitRisingEdge,
Trigger_WaitRisingEdge,
Impuls,
WaitTimeOut
);
-- State vector declaration
ATTRIBUTE state_vector : string;
ATTRIBUTE state_vector OF fsm : ARCHITECTURE IS "current_state" ;
-- Declare current and next state signals
SIGNAL current_state : STATE_TYPE ;
SIGNAL next_state : STATE_TYPE ;
-- Declare any pre-registered internal signals
SIGNAL ImpulsOut_cld : std_logic ;
SIGNAL LoadCnt_cld : std_logic ;
BEGIN
----------------------------------------------------------------------------
clocked : PROCESS(
Systemclock,
Reset
)
----------------------------------------------------------------------------
BEGIN
IF (Reset = '0') THEN
current_state <= WaitRisingEdge;
-- Reset Values
ImpulsOut_cld <= '0';
LoadCnt_cld <= '0';
ELSIF (Systemclock'EVENT AND Systemclock = '1') THEN
current_state <= next_state;
-- Default Assignment To Internals
ImpulsOut_cld <= '0';
LoadCnt_cld <= '0';
-- State Actions for internal signals only
CASE current_state IS
WHEN WaitRisingEdge =>
ImpulsOut_cld <= '0';
LoadCnt_cld <= '0';
WHEN Trigger_WaitRisingEdge =>
ImpulsOut_cld <= '0';
LoadCnt_cld <= '0';
WHEN Impuls =>
ImpulsOut_cld <= '1';
LoadCnt_cld <= '1';
WHEN WaitTimeOut =>
ImpulsOut_cld <= '1';
LoadCnt_cld <= '0';
WHEN OTHERS =>
NULL;
END CASE;
END IF;
END PROCESS clocked;
----------------------------------------------------------------------------
nextstate : PROCESS (
CarryOut,
FallingEdge_In,
current_state
)
----------------------------------------------------------------------------
BEGIN
CASE current_state IS
WHEN WaitRisingEdge =>
IF (FallingEdge_In = '1') THEN
next_state <= Trigger_WaitRisingEdge;
ELSE
next_state <= WaitRisingEdge;
END IF;
WHEN Trigger_WaitRisingEdge =>
IF (FallingEdge_In = '0') THEN
next_state <= Impuls;
ELSE
next_state <= Trigger_WaitRisingEdge;
END IF;
WHEN Impuls =>
IF (CarryOut = '0') THEN
next_state <= WaitTimeOut;
ELSE
next_state <= Impuls;
END IF;
WHEN WaitTimeOut =>
IF (CarryOut = '1') THEN
next_state <= WaitRisingEdge;
ELSE
next_state <= WaitTimeOut;
END IF;
WHEN OTHERS =>
next_state <= WaitRisingEdge;
END CASE;
END PROCESS nextstate;
-- Concurrent Statements
-- Clocked output assignments
ImpulsOut <= ImpulsOut_cld;
LoadCnt <= LoadCnt_cld;
END fsm;
Increasing the wheel perimeter
The component PerimeterImpulsGen provides pulses on the output to the input Inc_Wheel of the ProcessingUnit. The architecture body of this component contains a process without signals specified in a sensitivity list.
A process statement is always active and executes a loop at all time if not suspended.
Synchronisation can be obtained with several solutions:
- Holding an event until a signal defined in the sensitivity list
- Waiting until a condition becomes true (WAIT UNTIL)
- Waiting for a certain period (WAIT FOR)
- Suspend the process for ever (WAIT)
This process assigns the respective signal levels corresponding to the scheduling, as specified by the after clause. All time values are related to the simulation time zero mark. The WAIT statement suspends the process.
ARCHITECTURE flow OF PerimeterImpulsGen IS
BEGIN
---------------------------------------------------------------------------
process0 : PROCESS
---------------------------------------------------------------------------
BEGIN
WheelPerimeterAdjust <= '1',
'0' AFTER 5 ms,
'1' AFTER 6 ms,
'0' AFTER 10 ms,
'1' AFTER 11 ms,
'0' AFTER 15 ms,
'1' AFTER 16 ms,
'0' AFTER 20 ms,
'1' AFTER 21 ms;
wait;
END PROCESS process0;
END flow;
Previous page | Content | Home