過程(Procedures)
- Always塊 – 組合邏輯 (Always blocks – Combinational)
由于數字電路是由電線相連的邏輯門組成的,所以任何電路都可以表示為模塊和賦值語句的某種組合.
然而,有時這不是描述電路最方便的方法.
兩種always block是十分有用的:
- 組合邏輯:
always @(*)
- 時序邏輯:
always @(posedge clk)
always @(*)
就相當于賦值語句–assign,因此選擇哪一種語法僅僅取決與方便程度.
block內還有更豐富的語句集,比如if-else,case等等.但不能包含連續賦值,即不可包含assign,因為他與always @(*)沖突.
以下語句是等價的
assign out1 = a & b | c ^ d;
always @(*) out2 = a & b | c ^ d;
- Module Declaraction
module top_module(input a, input b,output wire out_assign,output reg out_alwaysblock
);
- Solution
// synthesis verilog_input_version verilog_2001
module top_module(input a, input b,output wire out_assign,output reg out_alwaysblock
);assign out_assign = a&b;always @(*) out_alwaysblock = a&b;
endmodule
- Always塊 – 時序邏輯 (Always blocks – Clocked)
verilog中有三種賦值方式:
- 連續賦值:
assign x = y;
不能在always-block內使用 - 阻塞賦值:
x = y;
, 只能在always-block內使用 - 非阻塞賦值:
x <= y
,只能在always-block內使用
請在組合邏輯中使用阻塞賦值,在時序邏輯中使用非阻塞賦值
否則將產生難以發現的錯誤
請實現如下電路:
- Module Declaraction
module top_module(input clk,input a,input b,output wire out_assign,output reg out_always_comb,output reg out_always_ff );
- Solution
// synthesis verilog_input_version verilog_2001
module top_module(input clk,input a,input b,output wire out_assign,output reg out_always_comb,output reg out_always_ff );
assign out_assign = a^b;always @(*) out_always_comb = a^b;always @(posedge clk) out_always_ff <= a^b;
endmodule
- If語句
if語句通常創建一個2對1的多路選擇器,如果條件為真,則選擇一個輸入,如果條件為假,則選擇另一個輸入.
以下兩種寫法是等價的:
always @(*) beginif (condition) beginout = x;endelse beginout = y;end
endassign out = (condition) ? x : y;
建立一個在a和b之間選擇的2對1多路選擇器.如果sel_b1和sel_b2都為真,則選擇b.否則,選擇a.
執行相同的操作兩次,一次使用assign語句,一次使用if語句.
- Module Declaraction
module top_module(input a,input b,input sel_b1,input sel_b2,output wire out_assign,output reg out_always );
- Solution
// synthesis verilog_input_version verilog_2001
module top_module(input a,input b,input sel_b1,input sel_b2,output wire out_assign,output reg out_always ); assign out_assign = (sel_b1&sel_b2)?b:a;always @(*) beginif(sel_b1&sel_b2) beginout_always = b;endelse beginout_always = a;endend
endmodule
- If語句引發的鎖存(latches)
以下代碼包含鎖存的錯誤行為.
- Module Declaraction
always @(*) beginif (cpu_overhe