Stepper-Motor-Control  v3.0.0
System on a Chip 2014 - Group 04
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros
motor_control_unit_tb.vhd
Go to the documentation of this file.
1 -------------------------------------------------------------------------------
2 --! @file motor_control_unit_tb.vhd
3 --! @author Marc Kossmann
4 --! @author Michael Riedel
5 --! @version v1.0.0
6 --! @date 05.12.2014
7 --!
8 --! @brief Testbench for Motor-Control-Unit Component
9 --! @details Tests full functionality of component
10 --!
11 --! @par History:
12 --! @details v0.1.0 26.11.2014 Riedel
13 --! - first draft
14 --! @details v0.1.1 27.11.2014 Riedel
15 --! - implemented first test-procedures
16 --! @details v0.1.2 28.11.2014 Riedel
17 --! - added documentation for GENERIC divider
18 --! - moved test-procedure-documentation to doxygen-heade
19 --! @details v0.1.3 30.11.2014 Kossmann
20 --! - changed divider to 250 to get 1 ms in simulation for 1 s
21 --! in real. Simulation takes longer but easier to measure
22 --! - Test-procedure must no commented in or out for easier readability
23 --! - initialized every signal
24 --! @details v0.1.4 30.11.2014 Riedel & Kossmann
25 --! - wiring new run signal for signal_generator
26 --! - added testcases
27 --! @details v0.1.5 03.12.2014 Kossmann
28 --! - implemented more testcases
29 --! @details v1.0.0 05.12.2014 Riedel & Kossmann
30 --! - release milestone 3b
31 -------------------------------------------------------------------------------
32 
33 --! Use Standard Library
34 LIBRARY ieee;
35 --! Use Logic Elements
36 USE ieee.STD_LOGIC_1164.all;
37 --! Use Arithmetic Functions
38 USE ieee.STD_LOGIC_arith.all;
39 --! Use Conversion Functions
40 USE ieee.STD_LOGIC_SIGNED.all;
41 
42 --! @brief Entity of testbench for motor_control_unit
44  GENERIC
45  (
46  --! @brief Prescaler for PWM-signal.
47  --! @details For this purpose 2,5 ms are used as minimal pulse-width.
48  --! @details The prescaler is calculated with the given and desired frequency
49  --! via the following formula:
50  --! \f{equation*}{
51  --! \text{prescaler} = \frac{f_{\text{clock}} \text{Hz}}{f_{\text{prescaler}} \text{Hz}}
52  --! \f}
53  --! e.g.:
54  --! \f{equation*}{
55  --! \left.\begin{aligned}
56  --! f_{\text{prescaler}} &= \frac{5}{2}\,\text{ms} \newline
57  --! &= 400\,\text{Hz} \newline\newline
58  --! \text{prescaler} &= \frac{50\,\text{Mhz}}{400\,\text{Hz}} \newline
59  --! &= 125000 \newline
60  --! \end{aligned}
61  --! \right\}
62  --! \qquad \text{pulse-width: 2.5 ms}
63  --! \f}
64  --! @details For simulation-purpose the divider was set to 125 for faster wave generation.
65  divider : integer := 125
66  );
67 END;
68 
69 --! @brief Architecture of testbench for motor_control_unit
70 ARCHITECTURE motor_control_unit_tb_arch OF motor_control_unit_tb IS
71 
72  SIGNAL motor_pwm : STD_LOGIC_VECTOR (3 DOWNTO 0) := "0000";
73  SIGNAL reset_n : STD_LOGIC := '1';
74  SIGNAL clock : STD_LOGIC := '0';
75  SIGNAL speed : STD_LOGIC_VECTOR (2 DOWNTO 0) := "000";
76  SIGNAL mode : STD_LOGIC_VECTOR (3 DOWNTO 0) := "0000";
77  SIGNAL direction : STD_LOGIC := '0';
78  SIGNAL run : STD_LOGIC := '0';
79  SIGNAL ir : STD_LOGIC := '0';
80  SIGNAL steps : STD_LOGIC_VECTOR (31 DOWNTO 0) := (others => '0');
81  SIGNAL motor_en : STD_LOGIC_VECTOR (1 DOWNTO 0) := "00";
82  CONSTANT left : STD_LOGIC := '0';
83  CONSTANT right : STD_LOGIC := NOT left;
84 
85  COMPONENT motor_control_unit
86  GENERIC
87  (
88  divider : INTEGER
89  );
90  PORT
91  (
92  motor_pwm : OUT STD_LOGIC_VECTOR (3 DOWNTO 0);
93  reset_n : IN STD_LOGIC;
94  clock : IN STD_LOGIC;
95  speed : IN STD_LOGIC_VECTOR (2 DOWNTO 0);
96  mode : IN STD_LOGIC_VECTOR (3 DOWNTO 0);
97  direction : IN STD_LOGIC;
98  run : IN STD_LOGIC;
99  ir : OUT STD_LOGIC;
100  steps : OUT STD_LOGIC_VECTOR (31 DOWNTO 0);
101  motor_en : OUT STD_LOGIC_VECTOR (1 DOWNTO 0)
102  );
103  END COMPONENT;
104 BEGIN
105  DUT : motor_control_unit
106  GENERIC MAP
107  (
108  divider => divider
109  )
110  PORT MAP
111  (
112  motor_pwm => motor_pwm,
113  reset_n => reset_n,
114  clock => clock,
115  speed => speed,
116  mode => mode,
117  direction => direction,
118  run => run,
119  ir => ir,
120  steps => steps,
121  motor_en => motor_en
122  );
123 
124  -- creates the clock
125  clock <= not clock after 10 ns;
126 
127  -- Test-procedure (1), reset_n
128  reset_n <= '0',
129  '1' after 20 ns;
130 
131  -- Test-procedure (2), Continuous Run with speed = 0, direction = left
132  -- 5 ms sim time for two pulses
133 -- run <= '1' after 20 ns;
134 -- mode <= "0001" after 20 ns;
135 -- direction <= left;
136 -- speed <= "000";
137 
138  -- Test-procedure (3), Continuous Run with speed = 1, direction = left, R/S toggle
139  -- 3 ms sim time for two pulses
140 -- run <= '1' after 20 ns,
141 -- '0' after 3000 us,
142 -- '1' after 3100 us;
143 -- mode <= "0001" after 20 ns;
144 -- direction <= left;
145 -- speed <= "001";
146 
147  -- Test-procedure (4), Continuous Run with speed = 7, direction = left
148  -- 15 us sim time for two pulses
149 -- run <= '1' after 20 ns;
150 -- mode <= "0001" after 20 ns;
151 -- direction <= left;
152 -- speed <= "111";
153 
154  -- Test-procedure (5), Continuous Run with speed = 7, direction = right
155  -- 15 us sim time for two pulses
156 -- run <= '1' after 20 ns;
157 -- mode <= "0001" after 20 ns;
158 -- direction <= right;
159 -- speed <= "111";
160 
161  -- Test-procedure (6), Chain of Steps - 1/4 rotation with speed = 7, direction = left
162  -- 750 us sim time for 1/4 rotation
163 -- register_interface_sim : process(clock)
164 -- begin
165 -- if (reset_n = '0') then
166 -- run <= '1';
167 --
168 -- elsif(rising_edge(clock)) then
169 -- if(ir = '1') then
170 -- run <= '0';
171 -- else
172 -- run <= run;
173 -- end if;
174 -- end if;
175 -- end process;
176 --
177 -- mode <= "0010" after 20 ns;
178 -- direction <= right;
179 -- speed <= "111" after 20 ns;
180 
181  -- Test-procedure (7), Chain of Steps - 1/4 rotation with speed = 7, direction = left/right switch
182  -- 750 us sim time for 1/4 rotation
183 -- register_interface_sim : process(clock)
184 -- begin
185 -- if (reset_n = '0') then
186 -- run <= '1';
187 -- elsif(rising_edge(clock)) then
188 -- if(ir = '1') then
189 -- run <= '0';
190 -- else
191 -- run <= run;
192 -- end if;
193 -- end if;
194 -- end process;
195 --
196 -- mode <= "0010" after 20 ns;
197 -- direction <= right,
198 -- left after 300 us;
199 -- speed <= "111" after 20 ns;
200 
201  -- Test-procedure (8), Chain of Steps - 1/4 rotation with speed = 7, direction = left with R/S restart
202  -- 750 us sim time for 1/4 rotation
203 -- register_interface_sim : process(clock)
204 -- begin
205 -- if (reset_n = '0') then
206 -- run <= '1';
207 -- elsif(rising_edge(clock)) then
208 -- if(ir = '1') then
209 -- run <= '0';
210 -- else
211 -- run <= '1';
212 -- end if;
213 -- end if;
214 -- end process;
215 --
216 -- mode <= "0010" after 20 ns;
217 -- direction <= right,
218 -- left after 300 us;
219 -- speed <= "111" after 20 ns;
220 
221  -- Test-procedure (9): Chain of Steps - 1/2 rotation with speed = 7, direction = left
222  -- 1100 us sim time for 1/2 rotation
223 -- register_interface_sim : process(clock)
224 -- begin
225 -- if (reset_n = '0') then
226 -- run <= '1';
227 -- elsif(rising_edge(clock)) then
228 -- if(ir = '1') then
229 -- run <= '0';
230 -- else
231 -- run <= run;
232 -- end if;
233 -- end if;
234 -- end process;
235 --
236 -- mode <= "0110" after 20 ns;
237 -- direction <= right,
238 -- left after 300 us;
239 -- speed <= "111" after 20 ns;
240 
241  -- Test-procedure (10): Chain of Steps - 1 rotation with speed = 7, direction = left
242  -- 2100 us sim time for 1 rotation
243 -- register_interface_sim : process(clock)
244 -- begin
245 -- if (reset_n = '0') then
246 -- run <= '1';
247 -- elsif(rising_edge(clock)) then
248 -- if(ir = '1') then
249 -- run <= '0';
250 -- else
251 -- run <= run;
252 -- end if;
253 -- end if;
254 -- end process;
255 --
256 -- mode <= "1010" after 20 ns;
257 -- direction <= right,
258 -- left after 300 us;
259 -- speed <= "111" after 20 ns;
260 
261  -- Test-procedure (11): Chain of Steps - 2 rotation with speed = 7, direction = left
262  -- 4200 us sim time for 2 rotation
263 -- register_interface_sim : process(clock)
264 -- begin
265 -- if (reset_n = '0') then
266 -- run <= '1';
267 -- elsif(rising_edge(clock)) then
268 -- if(ir = '1') then
269 -- run <= '0';
270 -- else
271 -- run <= run;
272 -- end if;
273 -- end if;
274 -- end process;
275 --
276 -- mode <= "1110" after 20 ns;
277 -- direction <= right,
278 -- left after 300 us;
279 -- speed <= "111" after 20 ns;
280 
281  -- Test-procedure (12): Reserved mode with speed = 7, direction = left
282  -- 200 us sim time for 2 rotation
283 -- register_interface_sim : process(clock)
284 -- begin
285 -- if (reset_n = '0') then
286 -- run <= '1';
287 -- elsif(rising_edge(clock)) then
288 -- if(ir = '1') then
289 -- run <= '0';
290 -- else
291 -- run <= run;
292 -- end if;
293 -- end if;
294 -- end process;
295 --
296 -- mode <= "1111" after 20 ns;
297 -- direction <= right,
298 -- left after 300 us;
299 -- speed <= "111" after 20 ns;
300 
301  finish_sim_time : PROCESS
302  BEGIN
303  WAIT FOR 10 ms;
304  ASSERT false
305  REPORT "simulation finished"
306  SEVERITY failure;
307  END PROCESS finish_sim_time;
308 END;
309 
in modeSTD_LOGIC_VECTOR(3 DOWNTO0)
mode to run motor with
in clockSTD_LOGIC
component clock
out motor_enSTD_LOGIC_VECTOR(1 DOWNTO0)
both enable signals for the motor
dividerinteger:=125000
Prescaler for PWM-signal.
in directionSTD_LOGIC
motor direction ('0' is left)
dividerinteger:=125
Prescaler for PWM-signal.
in reset_nSTD_LOGIC
resets the component
Motor Control Unit.
_library_ ieeeieee
Use Standard Library.
in runSTD_LOGIC
chip enable
out irSTD_LOGIC
IR signal set when motor stopped.
out motor_pwmSTD_LOGIC_VECTOR(3 DOWNTO0)
signal-bus for the motor pulse-width-modulation
Entity of testbench for motor_control_unit.
in speedSTD_LOGIC_VECTOR(2 DOWNTO0)
speed to run moter with
out stepsSTD_LOGIC_VECTOR(31 DOWNTO0)
number of steps motor did