HDLBits答案(10)_D触发器、同步与异步复位、脉冲边沿检测
D觸發器、同步與異步復位、脈沖邊沿檢測
HDLBits鏈接
D觸發器
定義:
D觸發器是一個具有記憶功能的,具有兩個穩定狀態的信息存儲器件,觸發器具有兩個穩定狀態,即"0"和"1",在一定的外界信號作用下,可以從一個穩定狀態翻轉到另一個穩定狀態。在這里解釋邊沿觸發的D觸發器,D觸發器在時鐘脈沖CP的前沿(正跳變0→1)發生翻轉,觸發器的次態(下一個狀態)取決于CP的脈沖上升沿到來之前D端的狀態,即次態Q=D。因此,它具有置0、置1兩種功能。由于在CP=1期間電路具有維持阻塞作用(即觸發器的輸出不變),所以在CP=1期間,D端的數據狀態變化,不會影響觸發器的輸出狀態,故邊沿D觸發器受干擾的可能性就降低了。
功能表:
| 0 | 時鐘上升沿 | 0 | 1 |
| 1 | 時鐘上升沿 | 1 | 0 |
| × | 0 | last Q | last QN |
| × | 1 | last Q | last QN |
同步復位與異步復位
同步復位:
顧名思義,同步復位就是指復位信號只有在時鐘上升沿到來時,才能有效。否則,無法完成對系統的復位工作。用Verilog描述如下:
always @ (posedge clk) beginif (!Rst_n)... end異步復位:
指無論時鐘沿是否到來,只要復位信號有效,就對系統進行復位。用Verilog描述如下:
always @ (posedge clk or negedge Rst_n) beginif (!Rst_n)... endD觸發器鞏固練習
題目描述1:
創建一個D觸發器。
Solution1:
module top_module (input clk, input d,output reg q );always @(posedge clk) beginq <= d;endendmodule[David說]:時序的always塊常使用非阻塞賦值。
題目描述2:
創建8個D觸發器,每個都由時鐘的上升沿觸發。
Solution2:
module top_module (input clk,input [7:0] d,output [7:0] q );always @(posedge clk) beginq <= d;endendmodule題目描述3:
創建8個d觸發器與主動高同步復位。所有D觸發器由clk的上升沿觸發。
Solution3:
module top_module (input clk,input reset, // Synchronous resetinput [7:0] d,output [7:0] q );always @(posedge clk) beginif(!reset)q <= d;elseq <=8'd0;endendmodule題目描述4:
創建8個D觸發器與主動高同步復位。觸發器必須被重置為0x34,而不是0。所有D觸發器應由clk的下降沿觸發。
Solution4:
module top_module (input clk,input reset,input [7:0] d,output [7:0] q );always @(negedge clk) beginif(!reset)q <= d;elseq <= 8'h0x34;endendmodule題目描述5:
創建8個D觸發器與主動高異步復位。所有D觸發器應由clk的上升沿觸發。
Solution5:
module top_module (input clk,input areset, // active high asynchronous resetinput [7:0] d,output [7:0] q );always @(posedge clk or posedge areset) beginif(areset) beginq <= 8'd0;endelse beginq <= d;endendendmodule[David說]:使用posedge areset時,只能使用if(areset)首先進行判斷而不能用if(!areset),否則會報錯。
題目描述6:
創建一個16D觸發器,有時我們僅需要修改部分觸發器中的值。字節使能信號控制當前時鐘周期中16個寄存器中哪個字節需被修改。byteena[1]控制高字節d[15:8],而byteena[0]控制低字節d[7:0]。
resetn是一個同步,低復位信號。
所有的D觸發器由時鐘的上升沿觸發。
Solution6:
module top_module (input clk,input resetn,input [1:0] byteena,input [15:0] d,output [15:0] q );always @(posedge clk) beginif(resetn) beginif(byteena[1])q[15:8] <= d[15:8];elseq[15:8] <= q[15:8];if(byteena[0])q[7:0] <= d[7:0];elseq[7:0] <= q[7:0];endelse beginq <= 16'd0;endendendmodule題目描述7:
實現下面的電路(鎖存器)
Solution7:
module top_module (input d, input ena,output q);always@(*)beginif(ena)beginq = d;endendendmodule題目描述8:
實現下面的電路
Solution8:
module top_module (input clk,input d, input ar, // asynchronous resetoutput q);always @(posedge clk or posedge ar) beginif(ar) beginq<=1'b0;endelse beginq<=d;endendendmodule題目描述9:
實現下面的電路
Solution9:
module top_module (input clk,input d, input r, // synchronous resetoutput q);always @(posedge clk) beginif(!r) beginq<=d;endelse beginq<=1'b0;endendendmodule題目描述10:
實現下面的電路
Solution10:
module top_module (input clk,input in, output out);always @(posedge clk) beginout <= (in ^ out);endendmodule題目描述11:
考慮下圖的電路:
假設要為這個電路實現分層的Verilog代碼,使用一個子模塊的三個實例,該子模塊中有一個觸發器和多路選擇器。為這個子模塊編寫一個名為top_module的Verilog模塊(包含一個觸發器和多路選擇器)
Solution11:
module top_module (input clk,input L,input r_in,input q_in,output reg Q);always @(posedge clk) beginQ <= L?r_in:q_in;endendmodule題目描述12:
考慮下圖的n-bit移位寄存器
為該電路的一個階段編寫一個Verilog模塊頂層模塊,包括觸發器和多路選擇器。
Solution12:
module top_module (input clk,input w, R, E, L,output Q );always @(posedge clk) begincase({E,L})2'b00:Q<=Q;2'b01:Q<=R;2'b10:Q<=w;2'b11:Q<=R;endcaseendendmodule題目描述13:
給定如圖所示的有限狀態機電路,假設D觸發器在機器開始之前被初始重置為零
Solution13:
module top_module (input clk,input x,output z ); reg Q1,Q2,Q3;always @(posedge clk) beginQ1 <= (x ^ Q1);Q2 <= (x & ~Q2);Q3 <= (x | ~Q3);endassign z = ~(Q1|Q2|Q3);endmodule題目描述14:
JK觸發器有下面的真值表。只使用D觸發器和邏輯門實現JK觸發器。注:Qold是時鐘上升沿前的D觸發器的輸出。
| 0 | 0 | Qold |
| 0 | 1 | 0 |
| 1 | 0 | 1 |
| 1 | 1 | ~Qold |
Solution14:
module top_module (input clk,input j,input k,output Q); always @(posedge clk) begincase({j,k})2'b00:Q<=Q;2'b01:Q<=1'b0;2'b10:Q<=1'b1;2'b11:Q<=~Q;endcaseendendmodule脈沖邊沿檢測
原理:
脈沖邊沿的特性:兩側電平發生了變化。
若檢測的是下降沿,那就是高電平變低電平。
若檢測的是上升沿,那就是低電平變高電平。
若檢測脈沖邊沿,只需將前后進來的信號做異或運算,即兩個電平不相同則是發生邊沿。
思路:
設計寄存器用來接收被檢測的信號;若{先進reg,后進reg}=2'b10,則是下降沿;
若{先進reg,后進reg}=2'b01,則為上升沿。
注:使用多個寄存器可以更好的檢測邊沿,防止干擾脈沖。具體看下例:
always @ (posedge clk or negedge rst_n) beginif(!rst_n) beginrs232_rx0 <= 1'b0;rs232_rx1 <= 1'b0;rs232_rx2 <= 1'b0;rs232_rx3 <= 1'b0;endelse beginrs232_rx0 <= rs232_rx;rs232_rx1 <= rs232_rx0;rs232_rx2 <= rs232_rx1;rs232_rx3 <= rs232_rx2;end end //這種方法可以濾除20-40ns的毛刺 assign neg_rs232_rx = rs232_rx3 & rs232_rx2 & ~rs232_rx1 & ~rs232_rx0;易分析,后進信號rs232_rx0,rs232_rx1,必須都為0,且先進信號rs232_rx3 ,rs232_rx2都必須為1,neg_rs232_rx 才會為1。則此時判斷為下降沿。
邊沿檢測鞏固練習
題目描述1:
對于8位向量中的每一位,檢測輸入信號何時從一個時鐘周期的0變化到下一個時鐘周期的1(正邊緣檢測)。輸出位應該在發生0到1轉換后的周期,如下示意圖所示:
Solution1:
module top_module (input clk,input [7:0] in,output [7:0] pedge );reg [7:0] temp_in;always @(posedge clk) begintemp_in <= in;pedge <= ~temp_in & in;endendmodule題目描述2:
對于8位向量中的每一位,檢測輸入信號何時從一個時鐘周期變化到下一個時鐘周期(檢測脈沖邊沿)。輸出位應該在發生轉換后的周期。
Solution2:
module top_module (input clk,input [7:0] in,output [7:0] anyedge );reg [7:0] temp_in;always @(posedge clk) begintemp_in <= in;anyedge <= temp_in ^ in;endendmodule題目描述3:
對于32位向量中的每一位,當輸入信號從一個時鐘周期的1變化到下一個時鐘周期的0時捕獲(捕捉下降沿),“捕獲”意味著輸出將保持1直到被reset(同步重置)。
每個輸出位的行為就像一個SR觸發器:輸出位應該在發生1到0轉換后的周期被設置(為1)。當復位為高時,輸出位應該在正時鐘邊緣復位(為0)。如果上述兩個事件同時發生,則reset具有優先級。
在下面示例波形的最后4個周期中,“reset”事件比“set”事件早一個周期發生,因此這里不存在沖突。
Solution3(1):
module top_module (input clk,input reset,input [31:0] in,output [31:0] out );reg [31:0] temp_in;reg [31:0] state;integer i;always @(posedge clk) begintemp_in <= in;for(i=0;i<32;i++) begincase({temp_in[i] & ~in[i],reset})2'b10:out[i]<=1'b1;2'b11:out[i]<=1'b0;2'b01:out[i]<=1'b0;default:out[i]<=out[i];endcaseendendendmoduleSolution3(2):
module top_module (input clk,input reset,input [31:0] in,output [31:0] out );reg [31:0] temp_in;always @(posedge clk) begintemp_in <= in;endalways @(posedge clk) beginif(reset)beginout<=32'b0;endelse beginout<=temp_in & ~in | out;endendendmodule題目描述4:
時鐘雙沿觸發器(不可使用下面形式的代碼,不可綜合)
always @(posedge clk or negedge clk)
Solution4(1):
module top_module (input clk,input d,output q );reg q1,q2;always @(posedge clk) beginq1<=d;endalways @(negedge clk) beginq2<=d;endassign q = clk?q1:q2; endmoduleSolution4(2):
module top_module (input clk,input d,output q );reg q1,q2;always @(posedge clk) beginq1<= d ^ q2;endalways @(negedge clk) beginq2<= d ^ q1;endassign q = q1 ^ q2; endmodule我們知道任何一個數異或一個數再異或同一個數,將得到本身。這就是最簡單的加密與解密原理。
Solution2相較于Solution1少了使用clk信號進行選擇,可以避免產生毛刺。推薦使用Solution2進行雙邊檢測。
總結
- 學習了D觸發器與同步異步復位的概念
- 學會了實際工程中常用的邊沿檢測電路
總結
以上是生活随笔為你收集整理的HDLBits答案(10)_D触发器、同步与异步复位、脉冲边沿检测的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: HDLBits答案(9)_卡诺图与最简S
- 下一篇: Questasim10.6c下载与安装教