1 -------------------------------------------------------------------------------
2 --! @file signal_generator.vhd
3 --! @author Marc Kossmann
4 --! @author Michael Riedel
8 --! @brief Signal Generator for Stepper-Motor-PWM
9 --! @details Generates the pulse-width and enable signals accordingly.
10 --! @details Motor State-Machine
12 --! @details v0.1.0 25.11.2014 Riedel & Kossmann
14 --! @details v0.1.1 26.11.2014 Riedel
15 --! - implemented signal-generator logic
16 --! @details v0.1.2 27.11.2014 Riedel
17 --! - added speed-statemachine to determine the correct
18 --! speed-integer when changes occur on the speed-bus
19 --! - added new CONSTANT `UNLIMITED_STEPS` for CR and IDLE, now
20 --! the IR won't be triggered everytime
21 --! - renamed the input `enable` to `prescaler`
22 --! @details v0.1.3 28.11.2014 Riedel & Kossmann
23 --! - fixed speed'Event, now the user can change the speed and
24 --! the signal_generator directly uses the new value
25 --! - removed wrong synchronization statements
26 --! @details v0.1.4 28.11.2014 Riedel
27 --! - removed `prescaler`-dependency in `pwm_generation`-process
28 --! @details v0.1.5 30.11.2014 Kossmann
29 --! - changed speed to speed_wire transfering process to async
30 --! - changed speed_wire /= old_speed_wire check to async
31 --! - fixed bug of t_pulse (pwm width) being systematical to long
32 --! (have to set pwm_5ms_counter to (speed_wire - 1))
33 --! @details v0.1.6 30.11.2014 Riedel & Kossmann
34 --! - fixed Chain of Steps Bug though evaluating run signal of mcu
35 --! @details v0.1.7 02.12.2014 Riedel & Kossmann
36 --! - changed structure and fixed bugs to get code working on fpga
37 --! @details v0.1.8 02.12.2014 Kossmann
38 --! - small adjustments for fulfill specification
39 --! @details v0.1.9 03.12.2014 Kossmann
40 --! - moved motor driver enable to mode_state machine
41 --! @details v0.1.10 05.12.2014 Riedel
42 --! - added few documentational lines
43 --! - corrected formatting and indention
44 --! @details v1.0.11 05.12.2014 Riedel & Kossmann
45 --! - release milestone 3b
46 --! @details v1.0.12 09.12.2014 Riedel & Kossmann
47 --! - swapped `rising_edge(prescaler)` with
48 --! `rising_edge(clock) AND prescaler = '1'`
49 --! @details v1.0.13 09.12.2014 Riedel
50 --! - restructured state-machine for modes
51 --! - created new process for motor power-management
52 --! - moved ir-logic to renamed `count_steps_and_set_ir`-process
53 --! @details v1.0.14 11.12.2014 Riedel & Kossmann
54 --! - corrected ir wire not being high for one clock
55 --! - corrected versioning mistake
56 -------------------------------------------------------------------------------
58 --! Use Standard Library
60 --! Use Logic Elements
61 USE ieee.std_logic_1164.
all;
62 --! Use Conversion Functions
63 USE ieee.std_logic_arith.
all;
64 --! Use Conversion Functions
65 USE ieee.std_logic_signed.
all;
67 --! @brief Signal Generator
70 clock : IN ;
--! component clock
71 run : IN ;
--! run or stop the signal_generator
74 mode : IN (3 DOWNTO 0);
--! mode to run motor with
75 speed : IN (2 DOWNTO 0);
--! speed to run moter with
77 ir : OUT ;
--! IR signal set when motor stopped
78 steps : OUT (31 DOWNTO 0);
--! number of steps motor did
79 motor_pwm : OUT (3 DOWNTO 0);
--! signal-bus for the motor pulse-width-modulation
80 motor_en : OUT (1 DOWNTO 0) --! both enable signals for the motor
84 --! @brief Architecture of signal generator
87 CONSTANT UNLIMITED_STEPS : := -1;
88 CONSTANT LEFT : := '0';
89 CONSTANT RIGHT : := NOT LEFT;
91 TYPE MODE_STATE_TYPE IS (IDLE, CR, COS_1_4, COS_1_2, COS_1, COS_2);
92 TYPE PWM_STATE_TYPE IS (ONE, TWO, THREE, FOUR);
94 SIGNAL mode_state : MODE_STATE_TYPE;
95 SIGNAL pwm_state : PWM_STATE_TYPE;
96 SIGNAL speed_wire : RANGE 0 TO 400;
97 SIGNAL old_speed_wire : RANGE 0 TO 400;
98 SIGNAL pwm_counter : RANGE 0 TO 400;
99 SIGNAL steps_to_run : ;
100 SIGNAL motor_en_wire : (1 DOWNTO 0);
101 SIGNAL motor_pwm_wire : (3 DOWNTO 0);
103 SIGNAL steps_output_wire : ;
111 ELSIF(rising_edge(clock) AND ir_wire = '0') THEN
114 mode_state <= COS_1_4;
116 mode_state <= COS_1_2;
122 IF (mode(1 DOWNTO 0) = "01") THEN
131 mode_processing :
PROCESS (mode_state)
135 steps_to_run <= UNLIMITED_STEPS;
137 steps_to_run <= UNLIMITED_STEPS;
145 steps_to_run <= 1599;
152 --- this block generates 9 combinational loops with latches
155 old_speed_wire <= speed_wire;
182 pwm_counter <= speed_wire;
183 ELSIF(speed_wire /= old_speed_wire) THEN
184 pwm_counter <= speed_wire;
186 IF(pwm_counter = 0) THEN
187 pwm_counter <= speed_wire;
189 pwm_counter <= pwm_counter - 1;
198 ELSIF(rising_edge(clock) AND prescaler = '1' AND pwm_counter = 0) THEN
225 pwm_output :
PROCESS (pwm_state)
229 motor_pwm_wire <= "1100";
231 motor_pwm_wire <= "0110";
233 motor_pwm_wire <= "0011";
235 motor_pwm_wire <= "1001";
239 power_motor :
PROCESS (
run, ir_wire)
241 IF(run = '0' OR ir_wire = '1') THEN
242 motor_en_wire <= "00";
244 motor_en_wire <= "11";
250 VARIABLE steps_counter : := 0;
254 steps_output_wire <= 0;
256 ELSIF(run = '0') then
258 steps_output_wire <= 0;
260 ELSIF(rising_edge(clock) AND prescaler = '1' AND pwm_counter = 0 AND mode_state /= CR AND mode_state /= IDLE) THEN
261 IF(steps_counter = steps_to_run) THEN
266 steps_output_wire <= steps_output_wire - 1;
268 steps_output_wire <= steps_output_wire + 1;
270 steps_counter := steps_counter + 1;
277 steps <= conv_std_logic_vector(steps_output_wire, 32);
278 END my_signal_generator;
in speedSTD_LOGIC_VECTOR(2 DOWNTO0)
speed to run moter with
in modeSTD_LOGIC_VECTOR(3 DOWNTO0)
mode to run motor with
in reset_nSTD_LOGIC
resets the component
out motor_enSTD_LOGIC_VECTOR(1 DOWNTO0)
both enable signals for the motor
out irSTD_LOGIC
IR signal set when motor stopped.
out motor_pwmSTD_LOGIC_VECTOR(3 DOWNTO0)
signal-bus for the motor pulse-width-modulation
in clockSTD_LOGIC
component clock
in runSTD_LOGIC
run or stop the signal_generator
out stepsSTD_LOGIC_VECTOR(31 DOWNTO0)
number of steps motor did
in prescalerSTD_LOGIC
input for minimum time-base
_library_ ieeeieee
Use Standard Library.
in directionSTD_LOGIC
motor direction ('0' is LEFT)