连续赋值语句通常用来描述组合逻辑电路,连续赋值的目标类型主要是标量线网和向量线网两种,标量线网如“wire a,b;
”,向量线网如“wire [3:0] a,b
”。连续赋值语句还可分为显示赋值语句和隐式连续赋值语句。
如下所示为显示连续赋值语句:
wire a,b,c; assign c = a & b;
如下所示为隐式连续赋值语句:
wire a,b; wire c = a & b;
如上所示,我们可以看到,显示连续赋值语句需要先类型声明(如wire),然后使用assign
关键字进行描述,而隐式赋值语句则是在声明的时候即进行赋值描述。需要知道的是,连续赋值语句只能用来对连线型变量进行驱动,而不能对寄存器型变量进行赋值。
initial
过程块在进行仿真时从仿真0时刻开始执行,整个initial过程块在执行完一次后就被挂起不再执行,如果模块中存在多个initial过程块,则每个initial过程块都是同时从0时刻开始并行执行的。initial过程语句通常用于仿真模块中对激励向量的描述,或用于给寄存器变量赋初值。
initial语句块不可被综合为实际电路。
如下所示为一个initial语句块对a,b,c赋值
module initial_tb1; reg a,b,c; initial begin a = 0; b = 1; c = 0; #100 a = 1; b = 0; #100 a = 0; c = 1; #100 b = 1; c = 0; #200; end endmodule
使用仿真工具查看波形可得如下所示
always语句块的触发由其后面的敏感事件列表决定,只要满足其敏感事件就执行该always过程块。always过程块的语法格式为
always@(<敏感事件列表>) 语句块;
敏感事件列表可以如下所示
@(a) // 当信号a的值发生改变时 @(a or b) // 当信号a或信号b的值发生改变时 @(posedge clock) // 当clock的上升沿到来时 @(negedge clock) // 当clock的下降沿到来时 @(posedge clk or negedge reset) // 当clk的上升沿到来或reset的下降沿到来时
always过程语句既可以描述时许逻辑电路,也可以描述组合逻辑电路,当我们使用不同的敏感事件列表时,会产生不同的电路形式,其设计要求如下:
如下为一个典型的组合逻辑电路,4选1多路数据选择器,
module mux4_1(out, in0, in1, in2, in3, sel); output out; input in0,in1,in2,in3; input [1:0] sel; reg out; // 过程块中被赋值信号需要定义为reg类型 always@(in0 or in1 or in2 or in3 or sel) begin case(sel) 2'b00: out = in0; 2'b01: out = in1; 2'b10: out = in2; 2'b11: out = in3; default:out = 1'bx; endcase end endmodule
经过综合后得到的电路图如下所示
如下是一个8位同步置数、同步清零计数器的代码,是一个典型的时序逻辑电路,
module counter(out, data, load, rst, clk); output out; input [7:0] data; input load, clk, rst; reg [7:0] out; // 过程块中被赋值信号需要定义为reg类型 always@(posedge clk) begin if(!rst) out = 8'h00; else if(load) out = data; else out = out + 1; end endmodule
经过综合后得到的电路图如下所示
我们在敏感信号列表中加入rst信号后就可以变成异步复位的计数器,
module counter(out, data, load, rst, clk); output out; input [7:0] data; input load, clk, rst; reg [7:0] out; // 过程块中被赋值信号需要定义为reg类型 always@(posedge clk or negedge rst) begin if(!rst) out = 8'h00; else if(load) out = data; else out = out + 1; end endmodule
经过综合后得到的电路图如下所示