-
Notifications
You must be signed in to change notification settings - Fork 195
Chapter 5: N bit prescaler
Examples of this chapter in github
Prescalers are used to slow down clock signals. A clock with a frequency of "f" goes into the input, and you get a lower frequency coming from the output. In this tutorial, we'll make an N-bit prescaler to make the LED blink at different frequencies.
For a N-bit prescaler, the formulas that relate the input frequencies and periods, with the ones at the output are:
Before implementing a N-bit prescaler, we are going to understand how a 2-bit prescaler works:
Internally, it's made of a 2-bit counter, whose outputs are d0 and d1. The most significant bit is the one that is sent as output signal. This counter increases with each rising edge of clk, that has a period of "T". If we see the output signals of its 2 bits: (d0 and d1):
we see that the period of d0 is 2 times T, and the d1 signal's is 4 times T. That means that every new bit duplicates the period of the previous signal. Following the general rule, the period of this 2-bit prescaler is: Tout = 2^2 * T = 4 * T (we can check that graphically).
The input frequency into the prescaler in the iCEStick is 12MHz. Applying the previous rule, we get this periods and frequencies table for prescalers with different number of bits (N). This gives us an idea of which value of N to choose, to make the LED blink.
Bits (N) | Frequency | Period | Visible |
---|---|---|---|
1 | 6 MHz | 0.167 usec | No |
2 | 3 MHz | 0.333 usec | No |
3 | 1.5 Mhz | 0.666 usec | No |
4 | 750 Khz | 1.333 usec | No |
5 | 375 Khz | 2.666 usec | No |
6 | 187.5 Khz | 5.333 usec | No |
7 | 93.75 KHz | 10.666 usec | No |
8 | 46.875 Khz | 21.333 usec | No |
9 | 23437.5 Hz | 42.666 usec | No |
10 | 11718.7 Hz | 85.333 usec | No |
11 | 5859.37 Hz | 170.66 usec | No |
12 | 2929.68 Hz | 341.33 usec | No |
13 | 1464.84 Hz | 682.66 usec | No |
14 | 732.42 Hz | 1.365 ms | No |
15 | 366.21 Hz | 2.73 ms | No |
16 | 183.1 Hz | 5.46 ms | No |
17 | 92.552 Hz | 10.92 ms | No |
18 | 45.776 Hz | 21.84 ms | No |
19 | 22.888 Hz | 43.69 ms | Yes |
20 | 11.444 Hz | 87.38 ms | Yes |
21 | 5.722 Hz | 174.76 ms | Yes |
22 | 2.861 Hz | 349.52 ms | Yes |
Human eyes have a refresh rate of around 25Hz. This means that anything happening at higher frequencies remain unnoticed. If we make the LED blink at a higher frequency, we'll see that as if was always on. (We won't see it blinking).
When you use the prescaler with an LED, you notice the blinking when using 19 bits or more. The more bits you use, the slower the LED will blink.
The code is almost the same as the one of the counter, but this time we introduce this new feature that this prescaler is parametric, this way the number of bits is determined by the N parameter. We can synthesize different sizes of prescalers by just changing this parameter.
//-- prescaler.v
//-- clk_in: input clock signal
//-- clk_out: output clock signal, lower frequency
module prescaler(input clk_in, output clk_out);
wire clk_in;
wire clk_out;
//-- Number of bits of the prescaler (default)
parameter N = 22;
//-- Register for implementing the N bit counter
reg [N-1:0] count = 0;
//-- The most significant bit goes through the output
assign clk_out = count[N-1];
//-- Counter: increases upon a rising edge
always @(posedge(clk_in)) begin
count <= count + 1;
end
endmodule
We define a N-bit register, that increases with each rising edge of the input clock signal. It's most significant bit is connected directly to the clk_out signal.
The prescaler is 22-bit by default, so clk_out's frequency will be around 2.9Hz. You only need to give N another value to change the output frequency.
The 12MHz clock signal from the iCEStick goes through the pin 21 of the FPGA. The clk_out signal is sent to the D1 LED (pin 99), so it blinks at the same frequency.
To synthesize, we execute:
$ make sint
Resource usage is:
Resource | Usage |
---|---|
PIOs | 2 / 96 |
PLBs | 5 / 160 |
BRAMs | 0 / 16 |
We upload into the FPGA by executing:
$ sudo iceprog prescaler.bin
The D1 LED will start blinking:
In this Youtube video you can see the LED blinking:
In the testbench we put the N-bit prescaler (N = 2 by default), a clock signal generator and a check block that executes every falling edge of the clock. This block has an internal register that increases each update, and its most significant bit is checked against clk_out, to assure that the latter is working properly. There's also a fourth block that initializes everything and waits for the simulation to finish.
The testbench code is the following:
//-- prescaler_tb.v
module prescaler_tb();
//-- Number of bits of the tested prescaler
parameter N = 2;
//-- Register for generating the clock signal
reg clk = 0;
//-- Prescaler output
wire clk_out;
//-- Register for checking if the prescaler works
reg [N-1:0] counter_check = 0;
//-- Instantiate the N-bit prescaler
prescaler #(.N(N)) //-- N parameter
Pres1(
.clk_in(clk),
.clk_out(clk_out)
);
//-- Clock generator. 2 time units period
always #1 clk = ~clk;
//-- Counter value check
//-- Each falling edge, the counter output is checked.
//-- and the expected value is increased
always @(negedge clk) begin
//-- Increase the check counter value
counter_check = counter_check + 1;
//-- The most significant bit must be the same as clk_out
if (counter_check[N-1] != clk_out) begin
$display("--->ERROR! Prescaler is malfunctioning");
$display("Clk out: %d, counter_check[2]: %d",
clk_out, counter_check[N-1]);
end
end
//-- Begin process
initial begin
//-- File to store the results
$dumpfile("prescaler_tb.vcd");
$dumpvars(0, prescaler_tb);
# 99 $display("END of simulation");
# 100 $finish;
end
endmodule
To simulate we execute:
$ make sim
In this simulation of the 2-bit prescaler we can see how indeed the output signal has a period 4 times greater than the input signal.
We repeat the simulation, but with a 3-bit prescaler, changing this line:
parameter N = 2;
The result is:
Now the output signal has a period 8 times greater that the input signal.
- Modify the prescaler with values of N = 18, 19, 20 and 21. Synthesize them and upload into the iCEStick.
- Make a simulation for N = 4
TODO
0 You are leaving the privative sector (EN)
1 ¡Hola mundo! (EN) (RU)
2 De un bit a datos (EN)
3 Puerta NOT (EN)
4 Contador de 26 bits (EN)
5 Prescaler de N bits (EN)
6 Múltiples prescalers (EN)
7 Contador de 4 bits con prescaler (EN)
8 Registro de 4 bits (EN)
9 Inicializador (EN)
10 Registro de desplazamiento (EN)
11 Multiplexor de 2 a 1 (EN)
12 Multiplexor de M a 1 (EN)
13 Inicializando registros (EN)
14 Registro de N bits con reset síncrono
15 Divisor de frecuencias
16 Contador de segundos
17 Generando tonos audibles
18 Tocando notas
19 Secuenciando notas
20 Comunicaciones serie asíncronas
21 Baudios y transmisión
22 Reglas de diseño síncrono
23 Controladores y autómatas finitos
24 Unidad de transmisión serie asíncrona
25 Unidad de recepción serie asíncrona
26 Memoria ROM
27 Memoria ROM genérica
28 Memoria RAM
29 Puertas triestado
30 Hacia el microprocesador y más allá