1. 程式人生 > 其它 >HDLBits Verilog(4)——Latches and Flip-Flops

HDLBits Verilog(4)——Latches and Flip-Flops

目錄

----- 81. D flip-flop -----

Problem Statement

A D flip-flop is a circuit that stores a bit and is updated periodically, at the (usually) positive edge of a clock signal.

D flip-flops are created by the logic synthesizer when a clocked always block is used. A D flip-flop is the simplest form of "blob of combinational logic followed by a flip-flop" where the combinational logic portion is just a wire.

Create a single D flip-flop.

Answer

module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//

    // Use a clocked always block
    //   copy d to q at every positive edge of clk
    //   Clocked always blocks should use non-blocking assignments
    
    always @(posedge clk)
		q <= d;

endmodule

----- 82. D flip-flops -----

Problem Statement

Create 8 D flip-flops. All DFFs should be triggered by the positive edge of clk.

Answer1

module top_module (
    input clk,
    input [7:0] d,
    output [7:0] q
);
    
    integer i;
	 always @(posedge clk) begin 
		for (i = 7; i >= 0; i = i - 1) begin
			q[i] <= d[i];
		end
	 end

endmodule

Answer2

module top_module(
	input clk,
	input [7:0] d,
	output reg [7:0] q);
	
	always @(posedge clk)
		q <= d;
	
endmodule

----- 83. DFF with reset -----

Problem Statement

Create 8 D flip-flops with active high synchronous reset(同步復位,高電平有效). All DFFs should be triggered by the positive edge of clk.

Answer

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output [7:0] q
);

     always @(posedge clk) begin
		if(reset == 1'b1)
			q <= 0;
		else
			q <= d;
	 end
    
endmodule

----- 84. DFF with reset value -----

Problem Statement

Create 8 D flip-flops with active high synchronous reset. The flip-flops must be reset to 0x34 rather than zero. All DFFs should be triggered by the negative edge of clk.

Answer

module top_module (
    input clk,
    input reset,
    input [7:0] d,
    output [7:0] q
);
    
    always @(negedge clk) begin
		if(reset == 1'b1)
			q <= 8'h34;
		else
			q <= d;
	 end

endmodule

----- 85. DFF with asynchronous reset -----

Problem Statement

Create 8 D flip-flops with active high asynchronous reset(非同步復位,高電平有效). All DFFs should be triggered by the positive edge of clk.

Answer

module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output [7:0] q
);
    
    always @(posedge clk or posedge areset) begin
	 	if(areset == 1'b1)
			q <= 0;
		else
			q <= d;
	end

endmodule

(批註:非同步復位需要將復位訊號寫入敏感列表中,並且註明是上升沿(高電平)有效還是下降沿(低電平)有效;同步復位不用寫入列表中)

----- 86. DFF with byte enable -----

Problem Statement

Create 16 D flip-flops. It's sometimes useful to only modify parts of a group of flip-flops. The byte-enable inputs control whether each byte of the 16 registers should be written to on that cycle. byteena[1] controls the upper byte d[15:8], while byteena[0] controls the lower byte d[7:0].

resetn is a synchronous, active-low reset(同步復位,低電平有效).

All DFFs should be triggered by the positive edge of clk.

Answer

module top_module (
    input clk,
    input resetn,
    input [1:0] byteena,
    input [15:0] d,
    output [15:0] q
);

    always @(posedge clk) begin
		if (resetn == 1'b0)
			q <= 0;
		else
			case(byteena)
				2'b00: q <= q;
				2'b01: q[7:0] <= d[7:0]; 
				2'b10: q[15:8] <= d[15:8];
				2'b11: q <= d;
			endcase
	end
    
endmodule

----- 87. D Latch -----

Problem Statement

Implement the following circuit:

Note that this is a latch(鎖存器), so a Quartus warning about having inferred a latch is expected.

Answer

module top_module (
    input d, 
    input ena,
    output q);
    
    always @(ena) begin
		if(ena == 1'b1)
			q <= d;
		else
			q <= q;
	end

endmodule

(批註:若在always列表改成posedge ena,會綜合出觸發器(flip-flops))

(鎖存器和觸發器的區別是:鎖存器對輸入電平(使能訊號)敏感,觸發器對時鐘訊號敏感)

----- 88. DFF (asynchronous reset) -----

Problem Statement

Implement the following circuit:

Answer

module top_module (
    input clk,
    input d, 
    input ar,   // asynchronous reset
    output q);
    
    always @(posedge clk or posedge ar) begin
		if (ar == 1'b1) 
			q <= 0;
		else
			q <= d;
	 end

endmodule

----- 89. DFF (synchronous reset) -----

Problem Statement

Implement the following circuit:

Answer

module top_module (
    input clk,
    input d, 
    input r,   // synchronous reset
    output q);
    
    always @(posedge clk) begin
		if (r == 1'b1) 
			q <= 0;
		else
			q <= d;
	end

endmodule

----- 90. DFF+gate -----

Problem Statement

Implement the following circuit:

Answer

module top_module (
    input clk,
    input in, 
    output out);
    
     wire io;
	 assign io = in ^ out;
	 my_dff my_dff1(.clk(clk), .d(io), .q(out));

endmodule

module my_dff(
	input clk,
	input d,
	output reg q );
	
	always @(posedge clk) 
		q <= d;
		
endmodule

----- 91. Mux and DFF (a) -----

Problem Statement

Consider the sequential circuit below:

Assume that you want to implement hierarchical Verilog code for this circuit, using three instantiations of a submodule that has a flip-flop and multiplexer in it. Write a Verilog module (containing one flip-flop and multiplexer) named top_module for this submodule. (批註:寫出子模組即可!!!)

Answer

module top_module (
	input clk,
	input L,
	input r_in,
	input q_in,
	output reg Q);
    
    wire out;
	assign out = L ? r_in : q_in;
	
	always @(posedge clk) 
		Q <= out;

endmodule

----- 92. Mux and DFF (b) -----

Problem Statement

Consider the n-bit shift register circuit shown below:

Write a Verilog module named top_module for one stage of this circuit, including both the flip-flop and multiplexers. (批註:與上題一樣,寫出子模組即可!!!)

Answer

module top_module (
    input clk,
    input w, R, E, L,
    output Q
);
    
     wire io1, io2;
	 assign io1 = E ? w : Q;
	 assign io2 = L ? R : io1;
	 
	 always @(posedge clk) begin
		Q <= io2;
	 end

endmodule

----- 93. DFFs and gates -----

Problem Statement

Given the finite state machine circuit as shown, assume that the D flip-flops are initially reset to zero before the machine begins.

Build this circuit.

Answer

module top_module (
    input clk,
    input x,
    output z
); 
    
    wire xor_l, and_l, or_l;
	wire Q1, Q2, Q3;
	wire Qn1, Qn2, Qn3;
	assign xor_l = x ^ Q1;
	assign and_l = x & Qn2;
	assign or_l  = x | Qn3;
	
	my_dff my_dff1 (.clk(clk), .d(xor_l), .q(Q1), .qn(Qn1));
	my_dff my_dff2 (.clk(clk), .d(and_l), .q(Q2), .qn(Qn2));
	my_dff my_dff3 (.clk(clk), .d(or_l),  .q(Q3), .qn(Qn3));
	
	assign z = ~(Q1 | Q2 | Q3);

endmodule

module my_dff(
	input clk,
	input d,
	output reg q,
	output qn
);

	always @(posedge clk) begin
		q <= d;
	end
    assign qn = ~q;

endmodule

(批註:若將qn = ~q寫入always塊中,將綜合出兩個D觸發器,與題目要求不符)

----- 94. Create circuits from truth table -----

Problem Statement

A JK flip-flop(JK觸發器) has the below truth table. Implement a JK flip-flop with only a D-type flip-flop and gates. Note: Qold is the output of the D flip-flop before the positive clock edge.

J K Q
0 0 Qold
0 1 0
1 0 1
1 1 ~Qold

Answer

module top_module (
    input clk,
    input j,
    input k,
    output Q); 
    
     wire [1:0] jk;
	 assign jk = {j, k};
	 
	 always @(posedge clk) begin
		case(jk)
			2'b00: Q <= Q;
			2'b01: Q <= 0;
			2'b10: Q <= 1;
			2'b11: Q <= ~Q;
		endcase
	 end

endmodule

----- 95. Detect an edge -----

Problem Statement

(檢測上升沿)

For each bit in an 8-bit vector, detect when the input signal changes from 0 in one clock cycle to 1 the next (similar to positive edge detection). The output bit should be set the cycle after a 0 to 1 transition occurs.

Here are some examples. For clarity, in[1] and pedge[1] are shown separately.

Answer

實現原理如下:

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] pedge
);
    
    reg [7:0] temp1, temp2;
	 always @(posedge clk) begin
		temp1 <= in;
		temp2 <= temp1;
	 end
	 assign pedge = ~temp2 & temp1;

endmodule

----- 96. Detect both edges -----

Problem Statement

(檢測上升沿和下降沿)

For each bit in an 8-bit vector, detect when the input signal changes from one clock cycle to the next (detect any edge). The output bit should be set the cycle after a 0 to 1 transition occurs.

Here are some examples. For clarity, in[1] and anyedge[1] are shown separately.

Answer

實現原理如下:

module top_module (
    input clk,
    input [7:0] in,
    output [7:0] anyedge
);
    
    reg [7:0] temp1, temp2;
	always @(posedge clk) begin
		temp1 <= in;
		temp2 <= temp1;
	end
	assign anyedge = (~temp2 & temp1) | (temp2 & ~temp1);

endmodule

----- 97. Edge capture register -----

Problem Statement

(捕獲輸入訊號的下降沿,捕獲後維持高電平,復位後變為低電平,即為捕獲暫存器)

For each bit in a 32-bit vector, capture when the input signal changes from 1 in one clock cycle to 0 the next. "Capture" means that the output will remain 1 until the register is reset (synchronous reset)(同步復位).

Each output bit behaves like a SR flip-flop(RS觸發器): The output bit should be set (to 1) the cycle after a 1 to 0 transition occurs. The output bit should be reset (to 0) at the positive clock edge when reset is high. If both of the above events occur at the same time, reset has precedence(優先權). In the last 4 cycles of the example waveform below, the 'reset' event occurs one cycle earlier than the 'set' event, so there is no conflict here.

In the example waveform below, reset, in[1] and out[1] are shown again separately for clarity.

Answer

實現原理如下:

module top_module (
    input clk,
    input reset,
    input [31:0] in,
    output [31:0] out
);
    
    reg [31:0] temp;
	always @(posedge clk) begin
		temp <= in;
		if(reset)
			out <= 32'b0;
		else
			out <= (temp & ~in) | out;
	end

endmodule

----- 98. Dual-edge triggered flip-flop -----

Problem Statement

(雙邊沿D觸發器)

You're familiar with flip-flops that are triggered on the positive edge of the clock, or negative edge of the clock. A dual-edge triggered flip-flop is triggered on both edges of the clock. However, FPGAs don't have dual-edge triggered flip-flops, and always @(posedge clk or negedge clk) is not accepted as a legal sensitivity list(敏感列表).

Build a circuit that functionally behaves like a dual-edge triggered flip-flop:

(Note: It's not necessarily perfectly equivalent: The output of flip-flops have no glitches(脈衝,毛刺), but a larger combinational circuit that emulates this behaviour might. But we'll ignore this detail here.)

Answer1

(上升沿和下降沿觸發要分開寫)

實現原理如下:

module top_module (
    input clk,
    input d,
    output q
);
    
     reg temp1, temp2;
	 always @(posedge clk)
		temp1 <= d;
	 
	 always @(negedge clk)
		temp2 <= d;
	 
	 always @(clk) begin
		if(clk)
			q = temp1;
		else
			q = temp2;
	 end

endmodule

Answer2

(網站給出的解法比較巧妙,利用了異或運算的可交換性)

module top_module(
	input clk,
	input d,
	output q);
	
	reg p, n;
	
	// A positive-edge triggered flip-flop
    always @(posedge clk)
        p <= d ^ n;
        
    // A negative-edge triggered flip-flop
    always @(negedge clk)
        n <= d ^ p;
    
    // Why does this work? 
    // After posedge clk, p changes to d^n. Thus q = (p^n) = (d^n^n) = d.
    // After negedge clk, n changes to p^n. Thus q = (p^n) = (p^p^n) = d.
    // At each (positive or negative) clock edge, p and n FFs alternately
    // load a value that will cancel out the other and cause the new value of d to remain.
    assign q = p ^ n;
    
    
	// Can't synthesize this.
	/*always @(posedge clk, negedge clk) begin
		q <= d;
	end*/
    
    
endmodule