Sequential Logic
Latches and Flip-Flops
·
D Latch
·
DFF
·
DFF
·
DFF+gate
·
Create circuit from truth table
·
Dual-edge triggered flip-flop
Dff
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 (See alwaysblock2). 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.
·
· Blocking & Non Blocking
Blocking
& Non Blocking
1. Blocking的語法 = //循序式的方式執行程式
Exp
:
always@(posedge
clock)
begin
Data
=
A&B; //
blocking會先執行第一行程式
OUT
=
A+B; // 緊接著再執行第二行程式
end
注意 : 電路都使用blocking的方式設計會造成電路串連的太長,導致延遲太多時間。
2. Non
blocking的語法 <= //平行式的方式執行程式
Exp
:
always@(posedge
clock)
begin
Data
<= A&B; // non
blocking會同時執行
OUT
<=
A+B; //
end
注意 : 電路都使用non
blocking的方式設計會造成電路面積加大(成本提高),因為並行處理的輸出都要額外給予一個暫存器來儲存。
對於新手而言,該如何準確的判斷哪些時候該選用blocking,哪些時候又該選用non
blocking來做處理,有相當程度的困難。因此通常會給予新手一些建議,避免設計電路上的錯誤。
1. 組合邏輯assign電路採用blocking,且必須搭配wire。
2. 循序邏輯always電路採用non
blocking,且必須搭配reg。
# 組合邏輯à與時間無關,大多作為運算用。(如加、減法器)
# 循序邏輯à與時間有關,大多作為記憶資料,但不能運算。(如正反器)
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) begin q<=d; //循序邏輯always電路採用non blocking,且必須搭配reg。 end endmodule |
Dff8
Create 8 D flip-flops. All DFFs should be
triggered by the positive edge of clk.
module top_module( input clk, input [7:0] d, output reg [7:0] q);
// Because q is a vector, this creates multiple DFFs. always @(posedge clk) q <= d;
endmodule |
Dff8r
Create 8 D flip-flops with active high
synchronous reset. All DFFs should be triggered by the positive edge of clk.
module top_module (
input clk,
input reset, //
Synchronous reset
input [7:0] d,
output [7:0] q );
always @(posedge clk) begin
if (reset)
q<=0;
else q <= d; end endmodule |
Dff8p
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.
module top_module ( input clk, input reset, input [7:0] d, output [7:0] q ); always @(negedge clk) begin if (reset) q<=8'h34; else q <= d; end endmodule |
Dff8ar
Create 8 D flip-flops with active high asynchronous reset. All DFFs
should be triggered by the positive edge of clk.
//
In Verilog, the sensitivity list looks strange. The FF's reset is sensitive
to the //
*level* of areset, so why does using "posedge areset" work? //
To see why it works, consider the truth table for all events that change the
input //
signals, assuming clk and areset do not switch at precisely the same time: // clk areset output // x
0->1 q <= 0; (because
areset = 1) // x
1->0 no change (always block
not triggered) // 0->1 0 q
<= d; (not resetting) // 0->1 1 q
<= 0; (still resetting, q was 0 before too) // 1->0 x no
change (always block not triggered) |
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) q<=8'h00; else q <= d; end endmodule |
Dff16e
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].
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<=16'h00; else begin case(byteena) 2'b00: q <= q; 2'b01: q <= {q[15:8], d[7:0]}; 2'b10: q <= {d[15:8], q[7:0]}; 2'b11: q <= d; endcase end end endmodule |
Exams/m2014
q4a
Implement the following circuit:
Note that this is a latch, so a Quartus warning about having
inferred a latch is expected.
module top_module ( input d, input ena, output q); always@(*) begin if (ena) q=d; end endmodule |
Exams/m2014
q4b
Implement the following circuit: input ar, // asynchronous reset
//正確 // input ar, asynchronous reset module top_module ( input clk, input d, input ar, // asynchronous reset output q); always @(posedge clk, posedge ar)begin if (ar) q<=0; else q<=d; end endmodule |
//錯誤 module top_module ( input clk, input d, input ar, // asynchronous reset output q); always @(posedge clk)begin if (ar) q<=0; else q<=d; end endmodule |
Exams/m2014
q4c
Implement the following circuit: input r, // synchronous reset
//同步式 D型 正反器 module top_module ( input clk, input d, input r, // synchronous reset output q); always @(posedge clk)begin if (r) q<=0; else q<=d; end endmodule |
Exams/m2014
q4d
Implement the following circuit:
module top_module ( input clk, input in, output out); wire d1; assign d1=out^in; d_ff u0(clk,d1,out); endmodule module d_ff ( input clk, // Clocks are used in sequential circuits input d, output reg q );// always@(posedge clk) begin q<=d; //循序邏輯always電路採用non blocking,且必須搭配reg。 end endmodule |
Mt2015
muxdff
Taken from ECE253 2015 midterm
question 5
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.
module top_module ( input clk, input L, input r_in, input q_in, output reg Q); always@(posedge clk)begin if(L)begin Q <= r_in; end else begin Q <= q_in; end end endmodule |
module
endmodule |
Exams/2014
q4a
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.
module top_module ( input clk, input w, R, E, L, output Q ); wire temp_d; assign temp_d= (L==1)? R : (E==1)?w:Q; always @ (posedge clk ) //觸發器 begin Q <= temp_d; end endmodule |
Exams/ece241
2014 q4
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.
module top_module ( input clk, input x, output z ); wire d1,d2,d3; wire q1,q2,q3; assign d1=x ^ q1; assign d2=x & (~q2); assign d3=x | (~q3); d_ff u0(clk,d1,q1); d_ff u1(clk,d2,q2); d_ff u2(clk,d3,q3); assign z=~(q1 | q2 |q3); endmodule module d_ff ( input clk, // Clocks are used in sequential circuits input d, output reg q );// always@(posedge clk) begin q<=d; //循序邏輯always電路採用non blocking,且必須搭配reg。 end endmodule |
Exams/ece241
2013 q7
A JK
flip-flop 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 |
module top_module ( input clk, input j, input k, output Q); always@(posedge clk) begin case ({j,k}) 2'b00: Q<=Q; 2'b01: Q<=1'b0; 2'b10: Q<=1'b1; 2'b11: Q<=~Q; endcase end endmodule |
Edgedetect
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.
具體的設計可以採用一個暫存器Q來存儲上一個時鐘沿的輸入值D,當暫存器與輸入D的值分別為1、0時,則檢測到下降沿。
如圖:
信號前一狀態 in_last 為 0 低電平,當前狀態 in 為 1 高電平,即可檢測出該信號的上升緣。因此電路組成:保存信號前一狀態的D觸發器 + 輸出組合邏輯 out = ~in_last & in 。電路結構見下的電路圖。
或 ???? out = ~in_last & in ????
module top_module (
input clk, input
[7:0] in,
output [7:0] pedge ); reg[7:0]
in_last; always@(posedge clk) begin in_last <= in; pedge <= ~in_last & in; end endmodule |
//錯誤 module top_module (
input clk,
input [7:0] in,
output [7:0] pedge ); reg[7:0]
in_last;
always@(posedge clk) begin in_last <= in; pedge <= in_last & ~in; end
endmodule |
Edgedetect2
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
1. 上升沿加下降沿檢測。
上升沿核心檢測邏輯: ~in_last
& in。
下降沿類似上升沿核心邏輯為:
in_last & ~in。
最後運用或邏輯組合起來即可。核心代碼:anyedge = (~in_last &
in) | (in_last & ~in)。
2. 互斥或邏輯檢測。邊沿檢測,從整體來看,即信號發生變化就進行檢測輸出。因此使用異或邏輯 。核心代碼: in^ in_last 。 (in xor in_last)
module top_module (
input clk,
input [7:0] in,
output [7:0] anyedge ); reg[7:0]
in_last; always @(posedge clk) begin
//D flip-flop in_last <= in; // Method1: posedge +negedge //assign anyedge = (~in_last & in) |
(in_last & ~in); // Method2: XOR anyedge <= in ^ in_last;
end endmodule |
Edgecapture
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: 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.
對於32bits向量中的每一位元,當輸入信號由1變為0時進行檢測(即下降沿檢測)。其中檢測表示在重定信號(同步)到達前,輸出將保持1。 每一個輸出位就像一個RS觸發器,即當對應位出現1 to 0的變化時,輸出位將置1;而當reset信號為高電平,輸出位元將在下一個時鐘的上升沿被重定。如果信號的下降沿和reset事件在同一時刻發生,將優先執行復位操作。在下圖示例波形的最後4個時鐘週期中,reset事件比‘set’事件早一個週期出現,因此這裡沒有前述衝突。 為清楚起見,in[1]和out[1]在波形中分別單獨顯示。
邊緣檢測輸出保持狀態1,直到reset信號到達
module top_module (
input clk,
input reset,
input [31:0] in,
output [31:0] out ); reg[31:0]
in_last;//in's last state always@(posedge clk)//D Flip-Flop in_last <= in;
always@(posedge clk) begin if(reset) out
<= 32'h0000_0000; else out
<= out | in_last &
~in; end endmodule |
Dualedge
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:
一般的觸發器都是時鐘上升沿或下降沿觸發的。雙邊沿觸發器則是在時鐘的兩個邊沿都會引起觸發。然而,FPGA沒有雙邊沿觸發的觸發器,且always@(posedge
clk, negedge clk)中的敏感事件清單不合乎語法。 設計一種電路,使其功能類似於雙邊沿觸發器。 Tips: 1)在FPGA中雖不能設計雙邊沿觸發器,但是能夠設計單獨的上升沿觸發器和下降沿觸發器。2)該問題屬於中等難度的電路設計問題,只需要對基本的Verilog語法有所掌握即可。
該問題有兩種解法,一種是Mux選擇輸出法,另一種是網站給出的XOR方法
Mux選擇輸出法
module top_module ( input clk, input d, output q ); reg neg_q, pos_q; always@(negedge clk)//negedge
triggered flip-flop neg_q <= d; always@(posedge clk)//posedge triggered
flip-flop pos_q <= d; assign q = clk ? pos_q : neg_q; //a mux for out endmodule |
XOR法
module top_module (
input clk,
input d,
output q
);
reg p, n;
always @(posedge clk) //
A positive-edge triggered flip-flop
p <= d
^ n;
always @(negedge
clk) // A negative-edge triggered
flip-flop
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 d^p. Thus q = (p^n) = (p^d^q) = 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;
endmodule
|