轉自:http://blog.csdn.net/lg2lh/article/details/8104551
最近一直忙着找工作。哎,希望保佑我通過二面吧。
verilog的脈衝檢測方法一直在用,就那幾句話,但一直沒想他的原理,今天一個同學說筆試的遇到這個了,我一想,要我寫還真寫不出來,不懂原理,怎麼寫啊。死記硬背是我不喜歡的。
網上搜了一下,總結一下幾種方法。首先介紹一下基本的原理。
脈衝邊沿的特性:兩側電平發生了變化
如上圖所示一個脈衝,既有下降沿也有上升沿(好像是廢話),系統的時鐘週期一定要比這個小,頻率越高越好。後面說爲什麼
如果檢測的是下降沿(通常的按鍵檢測),脈衝邊沿的特性就是兩側電平發生了變化,下降沿是高電平變低電平。
根據系統時鐘頻率檢測,如果前後進來的信號發生了變化,這裏用的是異或運算。即兩個電平不相同則是發生邊沿。
思路:設計兩個或多個一位的寄存器,用來接收被檢測的信號,系統時鐘來一次記一次輸入信號,如果用了兩個寄存器直接異或就可以了。
如果不爲0,則發生了邊沿,再拼接,拼接順序假定是{先進reg,後進reg},則若先進reg=1,後進位0,則是下降沿,即{先進reg,後進reg}=2’b10。
同理相反{先進reg,後進reg}=2’b01,則爲上升沿。如果用了多個寄存器則可以更好地檢測,防止干擾脈衝。具體看例3:
例1:兩個寄存器:
reg dly0;
reg dly1;
wire dc_clk;
always @(posedge clk or negedge rst)
begin
if(!rst)begin
dly0 <= 1'b0;
dly1 <= 1'b0;
end
else begin
dly0 <= fpga_io;\\fpga_io爲待測脈衝
dly1 <= dly0;
end
end
assigndc_clk= dly1 ^ dly0;//fpga_io邊沿檢測信號
這裏值檢測了邊沿,沒判斷下降還是上升。
也可以這樣:專門判斷是否是下降沿:
assign io_xor = dly1 & ~dly0;//因爲下降沿特徵: 先進來的是高電平,後進來的是低電平,(注意dly0爲始終爲後進信號)則後進取反再與先進。如果爲1,表示信號時下降沿。
判斷上升沿類似可推。
例2:兩個寄存器,判斷了上升還是下降
input data_clk//認爲待測數據的時候
reg pre_state;
always @(posedge sys_clk)
begin
pre_state <= data_clk;//利用reg下一個時鐘才生效的特性.
if({pre_state ,data_clk} == 0x01)//0x01上升沿,0x10下降沿
begin
....
end
end
例3 判斷下降沿。多個寄存器。
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
rs232_rx0 <= 1'b0;
rs232_rx1 <= 1'b0;
rs232_rx2 <= 1'b0;
rs232_rx3 <= 1'b0;
end
else begin
rs232_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.
則此時判斷爲下降沿。