YILDIRIM BEYAZIT UNIVERSITY EE 205 – DIGITAL DESIGN PRELIMINARY EXERCISE FOR LAB 6 FLIP-FLOP & COUNTER & CLOCK DIVIDER Background Knowledge: Introduction: A flip-flop is an edge-triggered memory circuit. We can implement a flip-flop behaviorally using Verilog, and use a bunch of flip-flops to implement a clock divider that blinks a number of LEDs. Also a clock divider’s frequency can be more precisely calculated by using different designs. A lot of interesting things can be built by combining arithmetic circuits and sequential elements. We can provide arithmetic circuits with timing references by integrating arithmetic circuits with flip-flops. An adder with a register file (an array of flip-flops) can be used to implement a counter that increases the number by 1 when the rising edge of the clock arrives.
D Flip-Flop (D-FF): A D flip-flop (D-FF) is one of the most fundamental memory devices. A D-FF typically has three inputs: a data input that defines the next state, a timing control input that tells the flip-flop exactly when to “memorize” the data input, and a reset input that can cause the memory to be reset to '0' regardless of the other two inputs (usually referred as asynchronous reset). Figure 1 below displays the block diagram for a D-FF.
Figure 1. D-FF block diagram
1
YILDIRIM BEYAZIT UNIVERSITY 8-bit Counter: A counter is no more than an adder with a flip-flop for each of the output bits. The block diagram of a counter is shown below in Fig. 2.
Figure 2. Block diagram of 8-bit counter When reset signal “rst� is asserted, the outputs of the counter (Q[7:0]) are 0. The outputs of flip-flops feed back to the input of the ripple-carry adder and present 0+1=1 at the input of the flip-flops. When the reset signal is de-asserted, the outputs turn to 1 after the rising edge of the clock arrives. And 1+1=2 will be presented at the inputs of the flip-flops. After the second rising edge of the clock arrives, 2 will show up on the outputs of the counter. As a result of the analysis, the flip-flops provide a timing reference (clock) to the adder so that the output of the counter is increased by 1 every time the rising edge of clock arrives.
Clock Divider: A clock signal is needed in order for sequential circuits to function. Usually the clock signal comes from a crystal oscillator on-board. The oscillator used on Digilent FPGA boards usually ranges from 50 MHz to 100 MHz. However, some peripheral controllers do not need such a high frequency to operate. There is a simple circuit that can divide the clock frequency by half. The circuit is shown in Fig. 3 below.
2
YILDIRIM BEYAZIT UNIVERSITY
Figure 3. Clock divider circuit Assume clkdiv is high initially. As din inverts the signal clkdiv, din is initially low. When the first rising edge of clock arrives, clkdiv is updated by the current din value and changes to '0'. As soon as clkdiv changes to '0', din will be pulled up to logic '1' by the inverter. When the next rising edge of clk occurs, clkdiv will change to logic '1' and din will change back to '0' after the propagation delay of the inverter. The waveform of the circuit is shown in Fig. 4. As a result, the period of clkdiv (the time between two adjacent rising edges) doubles the period of clk (i.e., the frequency of clkdiv is half of the clk frequency).
Figure 4. Clock divider waveform With this circuit, we can actually divide the clock by cascading the previous circuit, as displayed in Fig. 5 below.
3
YILDIRIM BEYAZIT UNIVERSITY
Figure 5. Cascade clock divider Each stage divided the frequency by 2. Suppose that the input clock frequency to the first stage is 100 MHz (1,000,000Hz). After the first stage, the frequency became 100MHz/2 = 50MHz. After the second stage, the frequency became 100MHz/(2â‹…2) = 25MHz. After n stage, the frequency became:
100 MHz 100000000 = Hz 2.2 ‌2 2n Another way to implement a clock divider is to use a counter with a comparator to condition a flip-flop with an inverter to implement a clock divider that can control the output frequency more precisely. The block diagram of such a clock divider is shown in Fig. 6.
Figure 6. Clock divider with a counter and a comparator In the block diagram, the counter increases by 1 whenever the rising edge of clk arrives. It also resets its output to '0' when it reaches the constant number defined in the constant block. The comparator compares the output of the counter with the pre-defined constant and asserts EQ if the output of counter is equal to the pre-defined constant. When EQ is asserted, the output of the clock divider flips.
4
YILDIRIM BEYAZIT UNIVERSITY Let's assume that the pre-defined number is 3, and the output of clock divider (clk_div) is initialized to 0. It takes three clock cycles before the output of the counter equals the pre-defined constant, 3. When it reaches 3, the output of clock divider (clk_div) turns to 1, and the counter resets itself. It takes another three cycles before the output of the counter equals the pre-defined constant, 3. When it reaches 3 again, clk_div turns back to 0. So it takes 6 clock cycles before clk_div goes to 1 and returns to 0 again. As a result, the frequency of clk_div is one sixth of the frequency of original clk.
Question 1: In this step, you are going to implement a D-FF with asynchronous reset. Follow the steps below for your Verilog code:
As the block diagram in Fig. 1 shows, D flip-flops have three inputs: data input (D), clock input (clk), and asynchronous reset input (rst, active high), and one output: data output (Q). In Verilog code:
module dff( input D, input clk, input rst, output Q );
To describe the behavior of the flip-flop, you should use an “always” block. On the contrary to combinational circuits, the output of flip-flop changes when a rising edge or falling edge of clock occurs or the reset is asserted. In other words, output Q is sensitive to clock signal clk and reset signal rst. So you can describe the circuit as follows: always at rising edge of clk or rising of rst, if rst is asserted, Q is driven to logic '0', else Q is driven by D. In Verilog code:
always @ (posedge(clk), posedge(rst)) begin if (rst == 1) Q <= 1'b0; else Q <= D; end
So the final Verilog implementation of you D-FF should look as follows:
`timescale 1ns / 1ps module dff( input D, input clk, input rst, output Q ); always @ (posedge(clk), posedge(rst)) begin if (rst == 1) Q <= 1'b0;
5
YILDIRIM BEYAZIT UNIVERSITY else
Q <= D;
end endmodule
Question 2: The block diagram of the clock divider is shown in Fig. 7. You can name the internal wire out of the flipflop clkdiv and the wire connecting to the input of D-FF din. Follow the steps below for your Verilog code:
Figure 7. Block diagram of clock divider
In this design, you need two inputs: on-board clock input clk, and a push button as reset signal rst. You have one output to blink an LED, so you can call it led.
module clk_divider( input clk, input rst, output led );
You need to declare all the internal wires you are going to use.
wire [26:0] din; wire [26:0] clkdiv;
You need to instantiate 27 flip-flops with 27 inverters to divide the clock frequency by 2^27 to 0.745Hz. To instantiate the first flip-flop with an inverter, the Verilog code should be as follows:
dff dff_inst0 ( .clk(clk), .rst(rst), .D(din[0]), .Q(clkdiv[0]) );
For the rest 26 flip-flops, you can copy the code above 26 times and change the names of the internal wire each port will map to. However, you can also use generate statement with a for loop in Verilog to generate the code. By observing the block diagram shown above in Fig. 4, starting from the second flipflop, rst port of D-FF is always connected to signal rst. If the port D is connected to signal din[i], then clk 6
YILDIRIM BEYAZIT UNIVERSITY port is connected to clkdiv[i-1] and Q port is connected to clkdiv[i]. So, you can generate the 26 D-FF as follows: genvar i; generate for (i = 1; i < 27; i=i+1) begin : dff_gen_label dff dff_inst ( .clk(clkdiv[i-1]), .rst(rst), .D(din[i]), .Q(clkdiv[i]) ); end endgenerate;
You can use the same generate statement to instantiate 27 inverters, or by observing the connections, the bus din is actually the inverse of bus clkdiv. So, instead of writing the generate statement, you can simply write one assign statement as follows:
assign din = ~clkdiv;
Connect the output of the flip-flop in the final stage to led.
assign led = clkdiv[26];
So the Verilog file of the design should be as follows:
`timescale 1ns / 1ps module clk_divider( input clk, input rst, output led ); wire [26:0] din; wire [26:0] clkdiv; dff dff_inst0 ( .clk(clk), .rst(rst), .D(din[0]), .Q(clkdiv[0]) ); genvar i; generate for (i = 1; i < 27; i=i+1) begin : dff_gen_label dff dff_inst ( .clk(clkdiv[i-1]), .rst(rst), .D(din[i]), .Q(clkdiv[i])
7
YILDIRIM BEYAZIT UNIVERSITY ); end endgenerate; assign din = ~clkdiv; assign led = clkdiv[26]; endmodule
Question 3: As with the previous lab works, you can draft a test bench to test the circuit out before implementing it on-chip. However, in this test bench, you need to emulate the clock signal and the rst signal. The clock signal is actually a constantly oscillating signal. Your board has an input clock frequency of 100 MHz, i.e., the period of the clock is 10 ns. Half of the period the clock is high, half of the period clock is low. In other words, every half of the period, 5 ns in this case, the clock will flip itself. To simulate the clock signal, instead of putting it in the initialize statement, you should use an always statement. `timescale 1ns / 1ps ... reg clk; always #5 clk = ~clk;
In the initialize block, we will initialize clk signal to 0 and hold rst high for 10ns to reset the clock divider. So, the Verilog Test Bench will look like this: `timescale 1ns / 1ps module tb; // Inputs reg clk; reg rst; // Outputs wire led; // Instantiate the Unit Under Test (UUT) clk_divider uut ( .clk(clk), .rst(rst), .led(led) ); always #5 clk = ~clk;
8
YILDIRIM BEYAZIT UNIVERSITY initial begin // Initialize Inputs clk = 0; rst = 1; #10 rst = 0; // Wait 100 ns for global reset to finish #100; end endmodule
Obtain the simulated waveform. You should see in the waveform that clkdiv[0] is half of the frequency of clk, and that clkdiv[1] is half of the frequency of clkdiv[2].
9