1. Objectives
-
Learn how to generate random numbers using a Linear Feedback Shift Register (LFSR).
-
Learn how to use counters to wait for specific amounts of time before performing an action.
2. Materials Required
-
An FPGA prototyping board.
-
Design and simulation software tools.
-
The
onehz
module from previous experiments.
3. Background
3.1. Reaction Timer
The reaction timer is a circuit that measures human response time to a given event. We will develop the reaction timer as a game the goes as follows:
-
A player starts the game.
-
After a random delay, an LED will turn on.
-
As soon as the LED is on, the player should respond by pushing a button.
-
The circuit measures the time between the LED turning on and the player’s response.
-
Depending on the response time, a message will be displayed, classifying the player’s response as either fast, good (average), or slow.
To design this circuit, we need two components: a random time generator, and a response time calculator.
This experiment is divided into two parts. In the first part, you will build the random time generator, which will generate the random time delay between the start signal and the LED turning on. In the second part, you will build the response time calculator, which will measure the time between the LED turning on and the player’s response.
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. The designer implementing this functional design, can either make each functional block as a stand-alone circuit, or merge two or more blocks into one circuit. This choice is left to the designer. Such decision can affect the complexity and the flexibility of the design.
3.2. Generating Random Numbers
Random numbers can be generated using a component called a Linear Feedback Shift Register (LFSR). An LFSR is a shift register with XOR feedback.
An n-bit LFSR can generate periodic sequences with a maximum period of 2n – 1. After the period is finished, the sequence will repeat. The placement of the XOR gates defines the period of the LFSR.
LFSRs in general can be described using polynomials that specify the specific bits used in constructing the XOR feedback.
An example of a maximal period LFSR is shown in the A 4-bit LFSR with Maximum Period Using Flip-Flops
figure. The corresponding Verilog implementation is also shown in the
Verilog Implementation of a 4-bit LFSR listing. The flip-flops used have an active-high
preset to initialize the register to the 1111
state.
module lfsr_4b (input clock, input preset, output reg [3:0] y);
always @(posedge clock)
begin
if (preset)
y <= 4'b1111;
else
begin
y <= { y[1] ^ y[0], y[3:1] };
end
end
endmodule
The polynomial that describes this LFSR is:
As apparent, the bits mentioned in the polynomial [1] are the ones XOR’ed, and the result is used as the input to the shift register. That is, by knowing the polynomial, you can build a circuit that generates pseudo-random numbers.
For this LFSR, the state |
If this LFSR is initialized to Q3 Q2 Q1 Q0 = 1111
, the
maximal period will be 15, and the output sequence will be as shown in
the Function Table of the 4-bit LFSR and the
Sequence of the 4-bit LFSR figure.
Cycle | Q3+ = Q0 ⊕ Q1 | Q2+ | Q1+ | Q0+ | Value |
---|---|---|---|---|---|
1 |
1 |
1 |
1 |
1 |
15 |
2 |
0 |
1 |
1 |
1 |
7 |
3 |
0 |
0 |
1 |
1 |
3 |
4 |
0 |
0 |
0 |
1 |
1 |
5 |
1 |
0 |
0 |
0 |
8 |
6 |
0 |
1 |
0 |
0 |
4 |
7 |
0 |
0 |
1 |
0 |
2 |
8 |
1 |
0 |
0 |
1 |
9 |
9 |
1 |
1 |
0 |
0 |
12 |
10 |
0 |
1 |
1 |
0 |
6 |
11 |
1 |
0 |
1 |
1 |
11 |
12 |
0 |
1 |
0 |
1 |
5 |
13 |
1 |
0 |
1 |
0 |
10 |
14 |
1 |
1 |
0 |
1 |
13 |
15 |
1 |
1 |
1 |
0 |
14 |
16 |
1 |
1 |
1 |
1 |
15 |
3.3. From Random Numbers to Random Delays
We would like to use the randomly generated number to determine the length of time to wait for user input. We can do that using a counter that counts up to the random number.
Counters, Revisited
Recall from previous experiments that a counter counts the edges of
an input signal, typically the |
In experiment 8 (Clock), you learned how to model a parameterized counter with configurable width. There are many other variations of counters. For example, synchronous vs. asynchronous clear, up counter vs. down counter, whether the counter can be loaded with an initial value or not, and so on.
The Verilog Description of a 2-bit Up Counter with Load Capability shows another example of counter implementation
with parallel load: it can set the counter value to a user-provided
value that can be loaded, in parallel, using a dedicated input pin for
each bit. A value is loaded using the data
input when the load
input is set to 1
.
module up_counter_2b (
input clock, reset, enable, load, [1:0] data,
output reg [1:0] count);
always @(posedge clock)
begin
if (reset)
count <= 0;
else if (load)
count <= data;
else if (enable)
count <= count + 1;
end
endmodule
4. Tasks
4.1. Design a 5-bit LFSR
-
Use the example 4-bit LFSR described in the “Generating Random Numbers” section as a guide. Analyze its circuit and propose a design for a 5-bit LFSR based on the polynomial:
\[1 + x^2 + x^5\] -
Write a Verilog module for your 5-bit LFSR design, named
lfsr_5b
. Simulate your design and verify that the sequence is maximal, i.e., period = 31.
4.2. Design a Down Counter
-
Use the 2-bit up counter described in the “From Random Numbers to Random Delays” section as a guide to design a 2-bit down counter with load.
The down counter should have a reset input that sets the counter to the value
2'b11
when set. In addition, the down counter should be loadable, which means that once a load input (load
) is set to1
, the counter is loaded with a value through the 2-bitdata
input. When the counter reaches 0, it should set an output signalzero
to1
. -
Write a Verilog module for your 2-bit down counter design with the given requirements.
Use th interface below for your design:
module down_counter_2b ( input clock, reset, enable, load, [1:0] data, output zero, reg [1:0] count);
-
Simulate your design and verify that the
down_counter_2b
module counts correctly from a loadable value n, i.e., outputs = n, n – 1, n – 2, … , 1, 0.
4.3. Counting Down Seconds
-
Use your 2-bit down counter to count seconds.
Use your counter with a clock input that has a frequency of 1 Hz.
Use the
onehz
module that you built in experiment 9 (Building a Digital Timer). Alternatively, you can use the following implementation.module onehz ( input clock, reset, output clock_1hz); reg [26:0] counter; assign clock_1hz = (counter == 27'h5f5e0ff); always @(posedge clock) begin if (reset || clock_1hz) counter <= 0; else counter <= counter + 1; end endmodule
-
Propose a design that loads some fixed number of seconds and starts counting down.
-
Write a Verilog module for your design. Name it
fixed_delay_counter
. Use the following module declaration:module fixed_delay_counter ( input clock, reset, enable, load, [1:0] data, output zero, [1:0] count);
-
Implement your
fixed_delay_counter
module and verify its correct operation.
4.4. Counting Down a Random Number of Seconds
-
The following Verilog module,
delay_counter
, finalizes the design by integrating all the required components.module delay_counter ( input clock, reset, load_rand, output led); wire enable_rand; wire [1:0] count; wire [4:0] random; wire zero; wire load_rand_q; assign led = zero & ~load_rand; assign enable_rand = ~led & load_rand_q; dff load_rand_ff (clock, reset, load_rand, 1'b1, load_rand_q); lfsr_5b lfsr (clock, reset, random); fixed_delay_counter second_counter (clock, reset, enable_rand, load_rand, {random[3], random[1]}, zero, count); endmodule
Here,
lfsr_5b
andfixed_delay_counter
are your modules that you implemented in the previous tasks.dff
is a D flip flop (see below).The user should first press the
reset
button, which will reset the LFSR. Then, he presses theload_rand
button, which will load the counter with a random number of seconds obtained from the LFSR. The 2-bit random number is composed of bit 1 and bit 3 from the 5-bit LFSR output. Note that when the user presses theload_rand
button, theonehz
module is reset. Once the counter reaches zero, the counter stops counting and theled
signal should be1
. Theled
signal remains1
until the user presses theload_rand
orreset
buttons.For the D flip flop, use the following Verilog module:
D Flip Flop Verilog Modulemodule dff ( input clock, reset, enable, d, output reg q); always @(posedge clock) if (reset) q <= 0; else if (enable) q <= d; endmodule
-
Implement your
delay_counter
module on an FPGA by connecting theclock
signal to the system clock (FPGA pinV10
), and other signals to the necessary buttons and LEDs, and test it for correct functionality. You may want to declarecount[1]
andcount[0]
as output signals to see the value loaded in the counter when theload_rand
button is pressed. -
Answer the following questions:
-
Why is the
led
output signal defined asled = zero & ~load_rand
? -
Why is the
load_rand
signal stored in a D flip flop to obtainload_rand_q
? -
Why is the
enable_rand
signal defined asenable_rand = ~led & load_rand_q
?
-