过程(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