HDLBits答案(10)_D触发器、同步与异步复位、脉冲边沿检测
D觸發(fā)器、同步與異步復(fù)位、脈沖邊沿檢測(cè)
HDLBits鏈接
D觸發(fā)器
定義:
D觸發(fā)器是一個(gè)具有記憶功能的,具有兩個(gè)穩(wěn)定狀態(tài)的信息存儲(chǔ)器件,觸發(fā)器具有兩個(gè)穩(wěn)定狀態(tài),即"0"和"1",在一定的外界信號(hào)作用下,可以從一個(gè)穩(wěn)定狀態(tài)翻轉(zhuǎn)到另一個(gè)穩(wěn)定狀態(tài)。在這里解釋邊沿觸發(fā)的D觸發(fā)器,D觸發(fā)器在時(shí)鐘脈沖CP的前沿(正跳變0→1)發(fā)生翻轉(zhuǎn),觸發(fā)器的次態(tài)(下一個(gè)狀態(tài))取決于CP的脈沖上升沿到來(lái)之前D端的狀態(tài),即次態(tài)Q=D。因此,它具有置0、置1兩種功能。由于在CP=1期間電路具有維持阻塞作用(即觸發(fā)器的輸出不變),所以在CP=1期間,D端的數(shù)據(jù)狀態(tài)變化,不會(huì)影響觸發(fā)器的輸出狀態(tài),故邊沿D觸發(fā)器受干擾的可能性就降低了。
功能表:
| 0 | 時(shí)鐘上升沿 | 0 | 1 | 
| 1 | 時(shí)鐘上升沿 | 1 | 0 | 
| × | 0 | last Q | last QN | 
| × | 1 | last Q | last QN | 
同步復(fù)位與異步復(fù)位
同步復(fù)位:
顧名思義,同步復(fù)位就是指復(fù)位信號(hào)只有在時(shí)鐘上升沿到來(lái)時(shí),才能有效。否則,無(wú)法完成對(duì)系統(tǒng)的復(fù)位工作。用Verilog描述如下:
always @ (posedge clk) beginif (!Rst_n)... end異步復(fù)位:
指無(wú)論時(shí)鐘沿是否到來(lái),只要復(fù)位信號(hào)有效,就對(duì)系統(tǒng)進(jìn)行復(fù)位。用Verilog描述如下:
always @ (posedge clk or negedge Rst_n) beginif (!Rst_n)... endD觸發(fā)器鞏固練習(xí)
題目描述1:
創(chuàng)建一個(gè)D觸發(fā)器。
Solution1:
module top_module (input clk, input d,output reg q );always @(posedge clk) beginq <= d;endendmodule[David說(shuō)]:時(shí)序的always塊常使用非阻塞賦值。
題目描述2:
創(chuàng)建8個(gè)D觸發(fā)器,每個(gè)都由時(shí)鐘的上升沿觸發(fā)。
Solution2:
module top_module (input clk,input [7:0] d,output [7:0] q );always @(posedge clk) beginq <= d;endendmodule題目描述3:
創(chuàng)建8個(gè)d觸發(fā)器與主動(dòng)高同步復(fù)位。所有D觸發(fā)器由clk的上升沿觸發(fā)。
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:
創(chuàng)建8個(gè)D觸發(fā)器與主動(dòng)高同步復(fù)位。觸發(fā)器必須被重置為0x34,而不是0。所有D觸發(fā)器應(yīng)由clk的下降沿觸發(fā)。
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:
創(chuàng)建8個(gè)D觸發(fā)器與主動(dòng)高異步復(fù)位。所有D觸發(fā)器應(yīng)由clk的上升沿觸發(fā)。
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說(shuō)]:使用posedge areset時(shí),只能使用if(areset)首先進(jìn)行判斷而不能用if(!areset),否則會(huì)報(bào)錯(cuò)。
題目描述6:
創(chuàng)建一個(gè)16D觸發(fā)器,有時(shí)我們僅需要修改部分觸發(fā)器中的值。字節(jié)使能信號(hào)控制當(dāng)前時(shí)鐘周期中16個(gè)寄存器中哪個(gè)字節(jié)需被修改。byteena[1]控制高字節(jié)d[15:8],而byteena[0]控制低字節(jié)d[7:0]。
resetn是一個(gè)同步,低復(fù)位信號(hào)。
所有的D觸發(fā)器由時(shí)鐘的上升沿觸發(fā)。
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:
實(shí)現(xiàn)下面的電路(鎖存器)
Solution7:
module top_module (input d, input ena,output q);always@(*)beginif(ena)beginq = d;endendendmodule題目描述8:
實(shí)現(xiàn)下面的電路
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:
實(shí)現(xiàn)下面的電路
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:
實(shí)現(xiàn)下面的電路
Solution10:
module top_module (input clk,input in, output out);always @(posedge clk) beginout <= (in ^ out);endendmodule題目描述11:
考慮下圖的電路:
假設(shè)要為這個(gè)電路實(shí)現(xiàn)分層的Verilog代碼,使用一個(gè)子模塊的三個(gè)實(shí)例,該子模塊中有一個(gè)觸發(fā)器和多路選擇器。為這個(gè)子模塊編寫(xiě)一個(gè)名為top_module的Verilog模塊(包含一個(gè)觸發(fā)器和多路選擇器)
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移位寄存器
為該電路的一個(gè)階段編寫(xiě)一個(gè)Verilog模塊頂層模塊,包括觸發(fā)器和多路選擇器。
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:
給定如圖所示的有限狀態(tài)機(jī)電路,假設(shè)D觸發(fā)器在機(jī)器開(kāi)始之前被初始重置為零
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觸發(fā)器有下面的真值表。只使用D觸發(fā)器和邏輯門(mén)實(shí)現(xiàn)JK觸發(fā)器。注:Qold是時(shí)鐘上升沿前的D觸發(fā)器的輸出。
| 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脈沖邊沿檢測(cè)
原理:
脈沖邊沿的特性:兩側(cè)電平發(fā)生了變化。
若檢測(cè)的是下降沿,那就是高電平變低電平。
若檢測(cè)的是上升沿,那就是低電平變高電平。
若檢測(cè)脈沖邊沿,只需將前后進(jìn)來(lái)的信號(hào)做異或運(yùn)算,即兩個(gè)電平不相同則是發(fā)生邊沿。
思路:
設(shè)計(jì)寄存器用來(lái)接收被檢測(cè)的信號(hào);若{先進(jìn)reg,后進(jìn)reg}=2'b10,則是下降沿;
若{先進(jìn)reg,后進(jìn)reg}=2'b01,則為上升沿。
注:使用多個(gè)寄存器可以更好的檢測(cè)邊沿,防止干擾脈沖。具體看下例:
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;易分析,后進(jìn)信號(hào)rs232_rx0,rs232_rx1,必須都為0,且先進(jìn)信號(hào)rs232_rx3 ,rs232_rx2都必須為1,neg_rs232_rx 才會(huì)為1。則此時(shí)判斷為下降沿。
邊沿檢測(cè)鞏固練習(xí)
題目描述1:
對(duì)于8位向量中的每一位,檢測(cè)輸入信號(hào)何時(shí)從一個(gè)時(shí)鐘周期的0變化到下一個(gè)時(shí)鐘周期的1(正邊緣檢測(cè))。輸出位應(yīng)該在發(fā)生0到1轉(zhuǎn)換后的周期,如下示意圖所示:
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:
對(duì)于8位向量中的每一位,檢測(cè)輸入信號(hào)何時(shí)從一個(gè)時(shí)鐘周期變化到下一個(gè)時(shí)鐘周期(檢測(cè)脈沖邊沿)。輸出位應(yīng)該在發(fā)生轉(zhuǎn)換后的周期。
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:
對(duì)于32位向量中的每一位,當(dāng)輸入信號(hào)從一個(gè)時(shí)鐘周期的1變化到下一個(gè)時(shí)鐘周期的0時(shí)捕獲(捕捉下降沿),“捕獲”意味著輸出將保持1直到被reset(同步重置)。
每個(gè)輸出位的行為就像一個(gè)SR觸發(fā)器:輸出位應(yīng)該在發(fā)生1到0轉(zhuǎn)換后的周期被設(shè)置(為1)。當(dāng)復(fù)位為高時(shí),輸出位應(yīng)該在正時(shí)鐘邊緣復(fù)位(為0)。如果上述兩個(gè)事件同時(shí)發(fā)生,則reset具有優(yōu)先級(jí)。
在下面示例波形的最后4個(gè)周期中,“reset”事件比“set”事件早一個(gè)周期發(fā)生,因此這里不存在沖突。
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:
時(shí)鐘雙沿觸發(fā)器(不可使用下面形式的代碼,不可綜合)
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我們知道任何一個(gè)數(shù)異或一個(gè)數(shù)再異或同一個(gè)數(shù),將得到本身。這就是最簡(jiǎn)單的加密與解密原理。
Solution2相較于Solution1少了使用clk信號(hào)進(jìn)行選擇,可以避免產(chǎn)生毛刺。推薦使用Solution2進(jìn)行雙邊檢測(cè)。
總結(jié)
- 學(xué)習(xí)了D觸發(fā)器與同步異步復(fù)位的概念
 - 學(xué)會(huì)了實(shí)際工程中常用的邊沿檢測(cè)電路
 
總結(jié)
以上是生活随笔為你收集整理的HDLBits答案(10)_D触发器、同步与异步复位、脉冲边沿检测的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
                            
                        - 上一篇: HDLBits答案(9)_卡诺图与最简S
 - 下一篇: Questasim10.6c下载与安装教