HDLBits(6)9.14
2 Verilog语言
2.4 程序
2.4.1 Always 模块1
组合逻辑:always @(*)
时序逻辑:always @(posedge clk)
对于组合逻辑电路,一般会用 * 代替所有输入变量,防止出现错误
assign 用于对线性信号赋值,always模块用于定义reg型信号(寄存器型)
always与assign存在一个细微的区别,
wire a;
reg b;
assign a = 1'b0;
always@(*)
b = 1'b0;
在这种情况下,做仿真时a将会正常为0, 但是b却是不定态。always@(*)中的*是指该always块内的所有输入信号的变化为敏感列表,也就是仿真时只有当always@(*)块内的输入信号产生变化,该块内描述的信号才会产生变化,而像always@(*) b = 1'b0;
这种写法由于1'b0一直没有变化,所以b的信号状态一直没有改变,由于b是组合逻辑输出,所以复位时没有明确的值(不定态),而又因为always@(*)块内没有敏感信号变化,因此b的信号状态一直保持为不定态。
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
2.4.2 Always 模块2
三种赋值方法:
连续型:assign a=b
不能在过程块中实现
过程阻塞型:x=y
只能在过程块中实现,用于组合逻辑
过程非阻塞型:x<=y
只能在过程块中实现,用于时序逻辑
使用以上三种方式,定义异或门(XOR)
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
2.4.3 Always if
两种定义2选1选择器的方式
always @(*) begin
if (condition) begin
out = x;
end
else begin
out = y;
end
end
assign out = condition?x:y;
练习:定义逻辑如下表所示的选择器
module top_module(
input a,
input b,
input sel_b1,
input sel_b2,
output wire out_assign,
output reg out_always );
always @(*)
begin
if (sel_b1 & sel_b2)
out_always = b;
else
out_always = a;
end
assign out_assign = sel_b1?(sel_b2?b:a):a;//两次选择逻辑
endmodule
2.4.4 Always if 2
//以下代码会生成锁存器产生错误,修改
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving );
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
end
//修改后
module top_module (
input cpu_overheated,
output reg shut_off_computer,
input arrived,
input gas_tank_empty,
output reg keep_driving ); //
always @(*) begin
if (cpu_overheated)
shut_off_computer = 1;
else
shut_off_computer = 0;
end
always @(*) begin
if (~arrived)
keep_driving = ~gas_tank_empty;
else
keep_driving = (~arrived);
end
endmodule