The logic for these operations was one of the items I
spent a while to understand. The situation is shown in
Figure 8, and the Verilog code that makes the quadrant
determination and manipulates the dividend, divisor, and
extra_angle registers appears in lines 165-192 of the
top_HMC5883L.v module. Notice that the naming of the
quadrants in Figure 8 is arbitrary.
Whew! After all the work, the end result is that the
module top_HMC5883L has as its most interesting output a
24-bit value that is the magnetic heading of the HMC5883L
sensor in positive radians. The mag_angle signal contains
14 bits of fraction, nine bits of integer, and ranges from 0
to 2 radians. This signal is provided to the motor control
unit, which compares it to a command heading (signal is
cmd_hdg) to determine whether the logic needs to activate
the wheel motors.
In comparison to the magnetic compass logic, the logic
for the motor control is much simpler. The motor control
module receives a commanded heading, the heading
angle of the HMC5883L chip, a signal to indicate that
calibration is complete, and forward/reverse commands.
Given these inputs, the logic determines how to pulse-width modulate the four motors on the Whippersnapper
Runt Rover. The flowcharts in Figure 9 and Figure
10 show the four concurrent logical “loops” that are
always happening inside top_hdg_ctrl.v. This
organization is presented to make the operation
clear to someone examining the code.
The “A” loop checks to see if the motors are
enabled, and if they are, determines whether there’s
a command to go forward, reverse, or turn in either
direction. The outputs of the “A” loop enable the
individual motors (via the tristate enable ports of the
top level buffers).
The “B” loop determines the width of the pulse
that will be applied to the motors when they are
commanded to turn. Depending on the size of the error
between the current magnetic heading and the
commanded heading, the length of pulses applied to the
turning motors will be longer, turning the motor faster.
The error value is calculated in loop “C,” but recall that
in HDL, all the assignments and clocked processes are
happening “at the same time,” with no consideration to
where they appear in the code file. (The error value is
available to loop B, even though the code appears below in
The local parameter values called FIRST_GEAR,
SECOND_GEAR, THIRD_GEAR, and FOURTH_GEAR are
counter values that are loaded into the register called
“speed.” The value in speed is used in the logic of loop D.
The C loop is a combination of the code that
determines the heading error (top_hdg_ctrl.v, asynchronous
assignments on lines 170-172) and the asynchronous
assignment to the motor_enable signal (top_hdg_ctrl.v, line
175). Unlike the other logic loops, this code is completely
asynchronous. In terms of the flowchart, it can be thought
of as tracing a single path through the flow that is always
for the tan-1
Figure 9. Loops “A”
and “B” of the motor
42 SERVO 12.2017
(It’s customary to draw the unit circle with the 0/2point to the right,
and to show north at the top of the page. With the sensor mounted on
the chassis, the 0/2radians point on the circle actually points south.)
Figure 10. Loops C and D of the motor
control function top_hdg_ctrl.v.