1. Objectives
-
Learn how to design a saturating BCD counter.
-
Learn how to measure user response time.
-
Finalize the reaction timer experiment.
2. Materials Required
-
An FPGA prototyping board.
-
Design and simulation software tools.
-
Seven-segment display interface module.
3. Background
In the previous experiment, we have built a random delay counter, which waits for a random number of seconds before turning on an LED for the player to see and react by pushing a push button. Therefore, we need now to design the part that would measure the time between the LED turning on and the player pushing the push button. Then, we need to classify how fast the response of the player was.
3.1. Design Overview
The Functional Block Diagram of the Final System figure shows the functional design of the system. The white area highlights the blocks you are going to build in this part of the experiment.
We need to design a component that would count the number of seconds between the LED turning on and the time at which the push button is pressed by the user.
To simplify this task, we will measure the response time by counting using binary coded decimal (BCD) numbers rather than binary numbers, which means we can display the value of the counter to the player easily.
We will use a saturating counter, which is a counter that, upon
reaching a preset maximum value, will stop counting rather than going
back to zero. The counter is driven by a two_khz module that
generates a 2-kHz signal; as a result, the counter has a
half-a-millisecond accuracy, i.e. 500 µs. Once the counting stops, the
output of the counter will be fed into a module that would classify
the response time as fast, medium, or slow.
This design is illustrated in the Component Block Diagram figure below. In this experiment, we will implement these two components shown in the figure, and will integrate them with the previously implemented components to obtain a complete, functional system.
3.2. Building a Saturating BCD Counter
|
Cascaded BCD Counters
Recall from experiment 9 (Building a Digital Timer) that a BCD counter is a mod-10 counter, and that BCD counters may be cascaded, such that when a digit counter reaches the maximum digit value of 9, it resets back to 0, and increments the counter of the next more significant digit. For more details, refer to experiment 9 manual. |
The Verilog Module for a Two-Digit Saturating BCD Counter below shows how to build a two-digit
saturating BCD counter, which will count from zero up to 99, and stop
at 99 until it is reset using the reset input signal. Once this
counter reaches the value of 99, the only way to get it out of that
state is to reset it.
|
Observe how the two-digit counter in this example is built by cascading two one-digit BCD counters. |
module bcd_counter_1d (
input clock, reset, enable,
output eq9, reg [3:0] q);
assign eq9 = q[3] & q[0];
always @(posedge clock)
if (reset)
q <= 4'b0000;
else if (enable)
if (eq9)
q <= 4'b0000;
else
q <= q + 1;
endmodule
module saturating_bcd_counter_2d (
input clock, reset, enable,
output eq99, [3:0] q1, q0);
wire eq9_0, eq9_1, enable_0, enable_1;
assign eq99 = eq9_0 & eq9_1;
assign enable_0 = enable & ~eq99;
assign enable_1 = enable_0 & eq9_0;
bcd_counter_1d bcd_0 (clock, reset, enable_0, eq9_0, q0);
bcd_counter_1d bcd_1 (clock, reset, enable_1, eq9_1, q1);
endmodule
In this experiment, we will need a three-digit saturating BCD counter.
3.3. User Response Comparator
The response comparator is the component that we will use to compare the value of the counter at the time of the user response against a standardized table that maps the response time to a response speed class (fast, medium, or slow).
Once the user presses the measure push button, the counter should stop counting, and the response comparator circuit will check the value of the counter and evaluates the user response time.
The comparator will generate the following three signals to categorize the user response time:
| Fast |
if the user response time is less than 400 |
| Medium |
if the user response time is 400 or greater but less than 800 |
| Slow |
if the user response time is between 800 and 999 |
Combinational logic can be designed to generate the three signals. Two K-maps can be used to derive the equations for the medium and slow signals. Then, the equation for the fast signal can be derived based on the other two signals.
|
The input of this circuit is the most significant digit (MSD) only of
the three-digit saturating BCD counter (i.e., |
4. Tasks
4.1. Design a Three-Digit Saturating BCD Counter
-
Write a Verilog module for a three-digit saturating BCD counter using the following module declaration:
module saturating_bcd_counter_3d ( input clock, reset, enable, output eq999, [3:0] q2, q1, q0); -
Simulate your three-digit saturating BCD counter and verify its correct functionality.
4.2. Build the Response Time Comparator
The response time comparator circuit determines whether the user’s response is fast, medium, or slow. See the User Response Comparator section for details.
-
Using two K-maps, derive the equations of the medium and slow signals. Then, deduce the equation of the fast signal.
-
Write a Verilog module to model the response time comparator circuit using the following module declaration:
module response_speed ( input [3:0] q, output fast, med, slow); -
Simulate the
response_speedmodule and verify its correct functionality.
4.3. Integrate the Reaction Timer Modules
The Reaction Timer Verilog Module, reaction_timer, below integrates the
following modules:
- saturating_bcd_counter_3d
- response_speed
- delay_counter, from experiment 10 (part 1 of this experiment).
along with other modules.
module reaction_timer (
input clock, reset, start, measure,
output led, [7:0] seg, [3:0] an);
wire [3:0] q2, q1, q0;
wire reset2 = reset | start;
wire clock_2khz, measure_q, error, error_q, eq999, fast, med, slow;
delay_counter m1 (clock, reset, start, led);
two_khz m2 (clock, reset2, clock_2khz);
assign error = ~led & measure;
dff m3 (clock, reset2, measure, 1'b1, measure_q);
dff m4 (clock, reset2, error, 1'b1, error_q);
assign enable = clock_2khz & led & ~measure_q;
saturating_bcd_counter_3d m5 (clock, reset2, enable, eq999, q2, q1, q0);
response_speed m6 (q2, fast, med, slow);
display7seg m7 (clock, reset2, q2, 4'b0000, q0, q1, seg, an,
slow, med, fast, error_q, measure_q, 1'b0, 1'b1);
endmodule
For the two_khz module, you can use the following Verilog Module for Generating a 2 kHz Signal.
module two_khz (
input clock, reset,
output clock_2khz);
reg [15:0] counter;
assign clock_2khz = (counter == 16'hc34f);
always @(posedge clock)
begin
if (reset || clock_2khz)
counter <= 0;
else
counter <= counter + 1;
end
endmodule
For the display7seg module, use the DISP7SEG.v file that will be
given to you in the lab.
-
Implement the
reaction_timermodule on the FPGA.-
The signals
segandanshould be connected to the seven-segment display unit. -
The
clocksignal should be connected to the board’s system clock (pinV10on the FPGA). -
The
startandmeasureinputs are the two push buttons that the user will use.
-
-
Test the correct operation of your circuit.
-
Press the
resetbutton. -
Press the
startbutton, which will load the down counter with a random number of seconds between 0 and 3. Once this random number of seconds elapses, the LED will light. Once the LED signal is 1, the counter will start counting and will stop once you hit themeasurebutton. -
Press the
measurebutton as soon as you see the LED light. Before pressing themeasurebutton, you will see the count displayed on the seven-segment display unit. Once you push themeasurebutton, the classification of your speed will be displayed on the seven-segment display unit. If you press themeasurebutton before the LED is on, an error message will be displayed.
-
-
Answer the following questions:
-
Why are the
measureanderrorsignals stored in flip-flops (dff) to obtainmeasure_qanderror_q? -
Why is the
enablesignal, that is used to enable the counter, implemented as:
enable = clock_2khz & led & ~measure_q? -
Why is the
reset2signal, which is used for resetting all components except thedelay_counter, implemented as:
reset2 = reset | start?
-