這里來記錄一下相似代碼之間的不同差異,比如同步復位與異步復位觸發器的對比,上升沿復位和下降沿復位的對比等等。這里主要使用ISE的綜合引擎。直接附上代碼和綜合后電路圖,有些會有部分講解。
一、異步復位與同步復位
我在復位電路里面講解了同步復位和異步復位的區別,這里就不詳細介紹了,鏈接如下:http://www.cnblogs.com/IClearner/p/6683100.html
(1)異步復位
異步復位的代碼如下所示:
module DFF1( input clk, input rst_n, input d, output reg q ); always@(posedge clk or negedge rst_n) if(!rst_n) q <= 0; //異步清 0,低電平有效 else q <= d; endmodule
綜合得到的電路圖如下所示:
可以看到使用了一個反相器單元和一個觸發器單元;從代碼中我們可以推斷出,這是一個高電平有效的、異步復位觸發器。
(2)同步復位
同步復位觸發器代碼如下所示,注意黑體部分
module DFF2( input clk, input rst_n, input d, output reg q ); always@(posedge clk )//注意這里有所不同 if(!rst_n) q <= 0; //同步清 0,低電平有效 else q <= d; endmodule
綜合得到的電路如下所示:
我們可以看到,也是由一個反向器單元和一個觸發器單元構成,注意,這里的觸發器跟上面的觸發器顯然不是同一個類型的觸發器,管腳名稱改變了;結合代碼我們可以知道,這個觸發器是高電平觸發、同步復位的觸發器(由于是輸入信號是低電平有效,所以加了個反相器)。
二、不同電平之間的復位差異
(1)高電平觸發的異步復位VS低電平觸發的異步復位
①高電平觸發的異步復位(異步置位)
綜合得到的電路如下所示:
根據代碼,容易推斷得出這是一個高電平觸發、異步復位的觸發器(或者叫異步置位),這也與前面的內容相符合(高電平觸發復位,所以不用加反相器)。
②低電平觸發的異步復位
代碼和電路跟 一(1)的代碼和電路相同,這里不進行重述。
(2)高電平觸發的同步復位VS低電平觸發的同步復位
①高電平觸發的同步復位
代碼如下所示:
1 module DFF4( 2 input clk, 3 input rst_r, 4 input d, 5 output reg q 6 ); 7 8 always@(posedge clk ) 9 if(rst_r) 10 q <= 0; 11 else 12 q <= d; 13 14 endmodule
綜合得到的電路如下所示:
可以知道,這是一個高電平有效、同步復位的觸發器單元。
②低電平觸發的同步復位
代碼和電路同一(2),這里不進行重述
三、阻塞賦值和非阻塞賦值
(1)阻塞賦值綜合的觸發器
代碼如下所示,這里為了使用高電平觸發的觸發器單元,寫出高電平復位:
1 module DFF_chain( 2 input clk, 3 input rst_r, 4 input d, 5 output reg q 6 ); 7 reg reg_m ; 8 always @(posedge clk )//high level reset,synchronization 9 if(rst_r)begin 10 reg_m = 0;//block 11 q = 0; 12 end else begin 13 reg_m = d; 14 q = reg_m ; 15 end 16 endmodule
綜合得到的電路如下所示:
可以看到,綜合得到只有一個觸發器,中間的觸發器變量reg_m被優化掉了,只剩下q這個觸發器。
(2)換個順序的非阻塞賦值的觸發器
把后面的這兩個語句對調一下,同時把中間的變量改個名字,改成reg_block(這里改名字只是為了區分后面的非阻塞賦值的情況)
即要綜合的代碼如下所示:
1 module DFF_chain( 2 input clk, 3 input rst_r, 4 input d, 5 output reg q 6 ); 7 reg reg_block ; 8 always @(posedge clk )//high level reset,synchronization 9 if(rst_r)begin//block 10 reg_block = 0; 11 q = 0; 12 end else begin //here has changed 13 q = reg_block ; 14 reg_block = d; 15 end 16 endmodule
綜合得到的電路如下所示:
可以看到,調換順序之后,得到了我們我們想要的觸發器鏈。
結論:描述時序邏輯使用阻塞賦值可能得到正確的結果,也可以得到不正確的結果,因此時序邏輯不建議使用阻塞賦值。
(3)非阻塞賦值綜合的觸發器
代碼如下所示:
1 module DFF_chain( 2 input clk, 3 input rst_r, 4 input d, 5 output reg q 6 ); 7 reg reg_m ; 8 always @(posedge clk )//high level reset,synchronization 9 if(rst_r)begin 10 reg_m <= 0;//non block 11 q <= 0; 12 end else begin 13 reg_m <= d; 14 q <= reg_m ; 15 end 16 endmodule
綜合得到的電路如下所示:
從電路圖中可以看到,綜合得到了兩個觸發器,中間的觸發器reg_m被保留下來了,達到了我們預想中的觸發器鏈。
(4)換個順序后的非阻塞賦值
跟前面的阻塞賦值一樣,我們換一下順序,代碼如下所示:
1 module DFF_chain( 2 input clk, 3 input rst_r, 4 input d, 5 output reg q 6 ); 7 reg reg_nonblock ; 8 always @(posedge clk )//high level reset,synchronization 9 if(rst_r)begin//non block 10 reg_nonblock <= 0; 11 q <= 0; 12 end else begin 13 q <= reg_nonblock ; 14 reg_nonblock <= d; 15 end 16 endmodule
綜合得到的電路如下所示:
從電路中可以看到,即使調換了順序,電路還是我們需要的觸發器鏈。
結論:描述時序邏輯,使用非阻塞賦值可以得到正確的結果,因此時序邏輯推薦使用非阻塞賦值。
(5)描述組合邏輯電路時的阻塞賦值和非阻塞賦值
阻塞賦值描述組合邏輯(加法器),代碼如下所示:
1 module Adder( 2 input a, 3 input b, 4 input c, 5 output reg q 6 ); 7 reg sum_block ; 8 always @(* ) 9 begin 10 sum_block = a + b ; 11 q = sum_block + c; 12 end 13 endmodule
綜合得到電路如下所示:
綜合得到的電路是一個加法器。
我們改成非阻塞賦值看看,代碼如下所示:
1 module Adder( 2 input a, 3 input b, 4 input c, 5 output reg q 6 ); 7 reg sum_block ; 8 always @(* ) 9 begin 10 sum_block <= a + b ; 11 q <= sum_block + c; 12 end 13 endmodule
綜合得到的電路:
綜合得到的電路也是一個加法器。
因此可以冒險地得到一個結論,無論是阻塞賦值還是非阻塞賦值,都可以描述組合邏輯,但是一般情況下,我們推薦使用阻塞賦值,一方面是對仿真有用,另一方面是區別于描述時序邏輯的非阻塞賦值。
最后我嘗試著在同一個塊中使用阻塞賦值和非阻塞賦值,ISE的綜合器報錯。
編輯:hfy
-
觸發器
+關注
關注
14文章
1996瀏覽量
61051 -
同步復位
+關注
關注
0文章
27瀏覽量
10704 -
異步復位
+關注
關注
0文章
47瀏覽量
13300
發布評論請先 登錄
相關推薦
評論