文章目录
- Verilog_HDL数字集成电路的设计与应用(chapter2,3)
-
-
- 2.3.4 逻辑运算符
- 2.3.5 按位运算符
- 2.3.6 归约运算符
- 2.3.7 移位运算符
- 2.3.8 条件运算符
- 2.3.9 连接和复制操作符
- 3.1数据流建模
- 3.2 行为级建模
-
- 3.2.1 过程语句
- 3.2.2 语句块
- 3.2.3 过程赋值语句
- 3.2.4 连续赋值过程中的句子
- 3.3结构化建模
-
- 3.3.1 模块级建模
- 课后习题
-
- 3.1 连续赋值句 与 过程赋值语句
- 3.2 连续赋值语句描述4选1数据选择器
- 3.3
- 3.4
- 3.5
- 3.8
- 3.10 case,casex,casez
- 3.14
-
Verilog_HDL数字集成电路设计与应用(chapter2,3)
//例2.3-2 module arith_tb; reg[3:0]a; reg[2:0]b; initial begin a = 4'b1111; b = 4'b011; $display("%b",a*b); ///结果是45的低四位 $display("%b",a/b); $display("%b",a b); end endmodule //例2.3-3 module rela_tb; reg[3:0]a,b,c,d; initial begin a = 3; b = 6; c = 1; d = 4'hx; $display(a<b); //结果为假(0) $display(d <= a); //结果为不定值(x) end endmodule //例2.3-4 module equal_tb; reg[3:0]a,b,c,d; initial begin a = 4'b0xx1; b = 4'b0xx1; c = 4'b0011; d = 2'b11; $display(a==b); //结果为不定值(x) $display(a===b); //...真(1) $display(c==d); //...真(1) $display(c===d); //...假(0) end endmodule
2.3.4 逻辑运算符
- 如果操作数中存在不定态x,逻辑操作的结果也是不定态的
2.3.5 按位运算符
- 五种类型的位置运算符
- 按位取反(~),按位与(&)、按位或(|),按位异或(^),按位同或( ^~)
- 两个不同长度的数据回自动按右对齐两个操作数,高补0
- 操作结果的位宽与操作数中位宽较大的位宽相同。
2.3.6 归约运算符
- 归约运算符
- 按位运算
- 单目运算符
- 结果:产生一个逻辑值 —— 缩位运算符
- 缩位运算符
- &、|、^、~ &、~ |、~ ^ 、^ ~
- 归约运算符的操作数只有一个
- 操作过程:设置 a 是一个,分别是a[0],a[1],a[2],a[3]。当对a 缩位操作时,首先对a[0] 和a[1] 缩位运算产生一位结果,然后将结果与a[2]缩位操作,然后a[3]最终产生一位操作结果
module cut_tb; reg[5:0]a; initial begin a = 6'b101011; $display("%b",&a); ///结果位1b0 $display("%b",|a); //结果位 1'b1 $display("%b",^a); // 结果为1'b0 ///移位运算符 b = a<<2; c = a>>3; $display("%b",b); $display("%b",c); end endmodule
2.3.7 移位运算符
- 左移运算符 <<
- 右移运算符 >>
- 用0 补位
2.3.8 条件运算符
- < 条件表达式>?< 表达式1 >:< 表达式2 >
- 结果:真(1)、假(0)、不定态(x)
- 如果条件表达式的运算结果不定态,模拟器将将表达式1的值与表达式2的值进行比较,形成条件表达式值。
//2.3-8 2选1数据选择器 module mux2(in1,in2,sel,out); input[3:0]in1,in2; input sel; output[3:0]out; wire[3:0]out; assign out = (!sel)?in1:in2; endmodule
2.3.9 连接和复制操作符
- 连接运算符({} :将几个信号或数值连接成一个整体信号
- 格式:{信号1、信号2、……,信号n的某些}
- 复制运算符({ {}}:将表达式放入双花括号中,将复制因子放入第一层括号中。
module con_rep_tb; reg[2:0]a; reg[3:0]b; reg[7:0]c; reg[4:0]d; reg[5:0]e; initial begin a = 3'b101; b = 4'b1110; c = {a,b}; //结果 8'b01011110 d = {a[2:1],b[2:0]}; e = {2{a}}; //复制操作,结果 6'b101101 end endmodule
3.1数据流建模
//3.1-1 显式连续赋值语句 module example1_assignment(a,b,m,n,c,y); input[3:0]a,b,m,n; output[3:0]c,y; wire[3:0]a,b,m,n,c,y; //声明语句 assign y = m|n //显式赋值语句
assign #(3,2,4)c=a&b; //显式连续赋值语句
endmodule
//3.1-2 隐式连续赋值语句
module example2_assignment(a,b,m,n,c,y,w);
input[3:0]a,b,m,n;
output[3:0]c,y,w;
wire[3:0]a,b,m,n; //声明语句
wire[3:0]y = m|n; //隐式赋值语句
wire[3:0]#(3,2,4)c=a&b; //隐式连续赋值语句
wire(label0,weak1)[3:0]#(2,1,3)w = (a^b)&(m^n); //隐式连续赋值语句
endmodule
3.2 行为级建模
3.2.1 过程语句
- initial过程语句
- 用于仿真模块中对激励向量的描述,或用于给寄存器变量赋初值
- 在过程语句(initial,always)中,被赋值信号必须定义为“reg"类型
3.2.2 语句块
//串行语句块:begin...end
module wave_tb1;
reg wave;
parameter T=10;
initial
begin //当块内有变量时,必须有块名,即 begin:块名
wave=0;
#T wave=1;
#T wave=0;
#T wave=1;
#T wave=0;
end
endmodule
//并行语句块:fork...join
module wave_tb2;
reg wave;
parameter T=10;
initial
fork
wave=0;
#T wave=1;
#(2*T) wave=0;
#(3*T) wave=1;
#(4*T) wave=0;
join
endmodule
3.2.3 过程赋值语句
// 3.2-8
//程序1
module block3(a,b,c,clk,sel,out);
input a,b,c,clk,sel;
output out;
reg out,temp;
always@(posedge clk)
begin
temp=a&b;
if(sel)out=temple;
else out=c;
end
endmodule
//程序2
module block4(a,b,c,clk,sel,out);
input a,b,c,clk,sel;
output out;
reg out,temp;
always@(posedge clk)
begin
temp<=a&b;
if(sel)out<=temp;
else out<=c; //非阻塞式赋值,产生两级流水线
end
endmodule
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7zTlijvK-1602333855033)(D:\BCRC\documents\work\digital\assets\image-20200314143447257.png)]
3.2.4 过程连续赋值语句
- 赋值语句与重新赋值语句:assign……deassign
- 强制语句与释放语句:force…… release
//3.2-9 使用assign,deassign设计异步清零D触发器
module assign_dff(d,clr,clk,q);
input d,clr,clk;
output q;
reg q;
always@(clr)
begin
if(!clr)
assign q=0;
else
deassign q;
end
always@(negedge clk) q=d;
endmodule
//3.2-10
module force_release(a,b,out);
input a,b;
output out;
wire out;
and(out,a,b);
initial
begin
force out=a|b;
#5;
release out;
end
endmodule
module release_tb;
reg a,b;
wire out;
force_relesse_tb U1(a,b,out);
initial begin
a=1,b=0;
end
endmodule
3.3结构化建模
3.3.1 模块级建模
//3.3-7 使用defparam语句修改参数值
module halfadder(a,b,s,c);
input a,b;
output c,s;
parameter xor_delay=2,and_delay=3;
assign #xor_delay s=a^b;
assign #and_delay c=a&b;
endmodule
module fulladder(p,q,ci,co,sum);
input p,q,ci;
output co,sim;
parameter or_delay=1;
wire w1,w2,w3;
halfadder U1(p,q,w1,w2);
halfadder U2(ci,w1,sum,w3);
or #or_delay U3(co,w2,w3);
endmodule
module top1(top1a,top1b,top1s,top1c); //修改半加器参数
input top1a,top1b;
output top1s,top1c;
defparam U1.xor_delay=4,U1.and_delay=5;
halfadder U1(top1a,top1b,top1s,top1c);
endmodule
module top2(top2a,top2b,top2ci,top2co,top2sum); //修改全加器参数
input top2a,top2b,top2ci;
output top2co,top2sum;
defparam U2.U1.xor_delay=6,
U2.U1.and_delay=7;
U2.or_delay=5;
fulladder U2(top2a,top2b,top2ci,top2co,top2sum);
endmodule
//3.3-10 cmos
开关级2输入与非门示例 module nnand2(a,b,y); input a,b; output y; supply0 Gnd; supply1 Vdd; //supply0,supply1为内部参量,分别表示低电平和高电平 wire im1; pmos g1(y,Vdd,a); pmos g2(y,Vss,b); nmos g3(y,im1,a); nmos g4(im1,Gnd,b); endmodule
课后习题
3.1 连续赋值语句 与 过程赋值语句
-
- 语法上:**关键词“assign”**标识
- 的数据类型必须是
- 连续赋值语句
- 连续赋值语句主要对,,对,进行描述
-
- 语法上:,无assign
- 只能对赋值
- 类别:使用 = 或 <=
- 阻塞赋值语句:
- 符号 ,各阻塞赋值语句;
- 执行顺序:计算右侧表达式,赋给左边变量
- 非阻塞赋值语句:
- 符号: ,各非阻塞赋值语句
- 执行顺序:计算右侧表达式,,再将结果赋给左边变量
- 阻塞赋值语句:
- 过程性赋值语句主要描述,,用于
- ,若有多个initial块,则在程序开始时并行执行;
-
- 两组过程性连续赋值语句可以实现连续赋值
- :只能对变量的连续赋值操作
- 使用assign给寄存器赋值之后,这个值将一直保持在这个寄存器上,直到遇到 deassign 为止
- :可以对操作,force语句的优先级高于assign
- force语句用于寄存器时,会将寄存器当前值覆盖,release之后寄存器值不变,直到被重新赋值。
- :只能对变量的连续赋值操作
- 两组过程性连续赋值语句可以实现连续赋值
3.2 连续赋值语句描述4选1数据选择器
module mux(out,in0,in1,in2,in3,add);
output out;
input in0,in1,in2,in3;
input[1:0] add;
wire out;
assign out=((~add[0])&(~add[1])&in0)||((~add[0])&(add[1])&in1)||((add[0])&(~add[1])&in2)||((add[0])&(add[1])&in3);
endmodule
3.3
- Verilog 常用复位:同步复位,异步复位
- 同步复位和异步复位
- 同步复位:时钟敏感,复位信号随时钟边沿触发有效
- 异步复位:电平敏感,复位信号与时钟无关
- 同步电路和异步电路
- 同步电路:统一时钟源,经过PLL分频后的时钟驱动模块也是同步电路。
- 异步电路:没有统一时钟源
- 同步逻辑、异步逻辑
- 同步逻辑:时钟之间有固定的因果关系
- 异步逻辑:………… 没有……………………
3.4
-
always:
-
敏感信号列表中信号值发生变化就执行
-
敏感信号可以是:边沿敏感型 或 电平敏感型
reg[3:0] a; reg[1:0] b; always@(posedge clk) a=4'b1011; b<=2'b10;
-
-
initial
-
只执行一次
-
多个initial过程块时,从时间0开始并行执行
-
initial块内的多条行为语句可以是顺序执行,也可以是并行执行
-
用途:,给变量赋初值
initial begin a=2'b11; b=3'o463; end
-
3.5
- begin-end:其中语句串行执行
- fork - join:其中语句并行执行
module begin_exam;
reg A;
reg B;
initial
begin
A=0,B=1;
#10 A=1,B=0;
#10 A=1,B=1;
#10 A=0,B=1;
#10 A=0,B=0;
#10 A=1,B=1;
end
endmodule
module fork_exam;
reg A;
reg B;
initial
fork
A=0,B=1;
#10 A=1,B=0;
#20 A=1,B=1;
#30 A=0,B=1;
#40 A=0,B=0;
#50 A=1,B=1;
join
endmodule
3.8
- 阻塞赋值语句
- =,顺序执行,前面的未执行完后面无法执行
- 非阻塞赋值语句
- <=,并行执行,前面的是否执行完不影响后面
//阻塞赋值
module register1(out,din,clk);
output[3:0] out;
input din,clk;
reg[3:0] out;
always@(posedge clk)
out[3]=out[2];
out[2]=out[1];
out[1]=out[0];
out[0]=din;
endmodule
//非阻塞赋值
module register2(out,din,clk);
output[3:0] out;
input din,clk
reg[3:0] out;
always@(posedge clk)
out[0]<=din;
out[1]<=out[0];
out[2]<=out[1];
out[3]<=out[2];
endmodule
3.10 case,casex,casez
3.14
module exam_14(Z,D,S);
output Z;
input[3:0] D;
input S1,S2;
wire S2not,S1not;
reg[3:0] T;
reg Z;
and3 U1(T[3],D[3],S1,S2);
and3 U2(T[2],D[2],S1,S2not);
and3 U3(T[1],D[1],S1not,S2);
and3 U4(T[0],D[0],S1not,S2not)
not U5(S1not,S1);
not U6(S2not,S2);
or4 U7(Z,T[0],T[1],T[2],T[3]);
endmodule
module and3(out,in1,in2,in3);
output out;
input in1,in2,in3;
reg out;
out=in1&in2&in3;
endmodule