【 1. 给端口选择正确的数据类型 】
首先记住:Verilog HDL 默认的类型是 wire 型。
内部电路模块中:输入的输入端口:线网型,输出的驱动端口:线网型、寄存器型。
外部连接电路模块时:连接输入端的:线网型、寄存器型,连接输出端的:线网型。
一个案例
我们通过一个【优秀】的案例来看看【错误】代码的编译
//2输入与门电路
module TEST(a,b,c,d,o1,o2);
input a,b,c,d;
output o1,o2;
reg a,b,c,d;
reg o1;
wire o2;
assign o1=c&&d; //与门实现形式1
always@(a or b) //与门实现形式2
begin
if(a)
o2=b;
else
o2=1'b0;
end
endmodule
编译后出现下图错误:
可以看出 a、b、c、d 不能声明为 reg 型(因为这四个都是 input 输入端口)
那么我们就把 reg a,b,c,d; 这一句注释掉就变成了 wire 型(Verilog HDL 默认的类型就是 wire 型),重新修改后编译得到:
可以看出 assign 这种连续赋值语句,被赋值的数据类型必须是 wire 型。
在 always 这种过程赋值语句,被赋值的数据类型必须是 reg 型。
那么我们把 reg o1; wire o2;改成 wire o1; reg o2; 重新修改后编译得到:
完结,撒花✿✿ヽ(°▽°)ノ✿
小结
- Verilog HDL 默认的类型是 wire 型。
- input 输入端口必须是 wire 型。
- assign 连续语句,被赋值的数据类型必须是 wire 型。
- always 过程语句,被赋值的数据类型必须是 reg 型。
【 2. 小于等于号 】
刚刚在思考一个问题,下面这行代码中, if 后的圆括号内, 程序会把Q赋值成 16’hE 呢?还是只进行小于等于的判断?
always@(*)
if(Q<=16'hE)
Q<=16'h0;
实践是检验真理的唯一标准,通过一个小代码测试后(对Verilog HDL中的小于等于号的检验测试),得知:在if () 圆括号内,程序只进行了小于等于的判断,并没有赋值。
---------------------------------------------------分割线------------------------------------------------------------
2020/11/4更新:
小于等于号后的变量后是分号;的就是赋值语句。
【 3. 阻塞赋值、非阻塞赋值 】
当有多条赋值语句紧紧连续的时候,阻塞赋值与非阻塞赋值才体现出区别。
- 阻塞赋值 =: 写在前面的语句先执行,写在后面的语句后执行,也就是说,它是顺序执行的。一般用于组合逻辑电路。
- 非阻塞赋值 <=:写在前面的语句与后面的语句同时执行,也就是说,它是并行执行的,跟书写顺序没有关系。一般用于时序逻辑电路。
【 4. 仿真时对端口设计要求 】
module TEST(in,out);
input wire in;
output reg out;
reg out_temp;
reg [1:0] q;
always@(posedge in)
begin
q=q+1;
if(q==3)
begin
q<=0;
out_temp=~out_temp;
out=~out;
end
end
endmodule
当仿真上面代码时,可选设计端口如下所示,仅有in,out两个,并没有out_temp、q这些其他变量:
这是因为,在设计Verilog HDL语言时,module 后括号内容的 端口列表 中并没有出现out_temp、q 这些其他变量。
将第一行更改为:
module TEST(in,out,out_temp);
出现报错:
可见,out_temp 这个端口并没有声明端口类型是输出( output)、输入( input)、 还是双向端口( inout )。
再将代码修改,最终代码为:
module TEST(in,out,out_temp);
input wire in;
output reg out,out_temp;
reg [1:0] q;
always@(posedge in)
begin
q=q+1;
if(q==3)
begin
q<=0;
out_temp=~out_temp;
out=~out;
end
end
endmodule
编译成功,如下图所示,可选设计端口也包括了out_temp。
小结
- module 文件名(); //括号内容为端口列表,仿真时欲设计时序、显示波形的端口必须在列表中列出。
- 每个端口除了必须在端口列表中列出外,还必须声明该端口是输出( output)、输入(input)、还是双向端口( inout )。
---------------------------------------------------分割线------------------------------------------------------------
2020/12/18更新:
一些内部端口也可以在不声明成input、output的情况下,添加至仿真列表中,但是有些可能不会出现在最终的仿真报告中。(Quartus9.0环境测试)
故最好应该先添加至仿真列表,再观察仿真报告中是否会出现响应端口,若未出现,则应在源文件中声明并放在输入输出端口列表。
【 5. 并行执行 】
当不考虑阻塞赋值和非阻塞赋值时。
在 Verilog HDL中,不同语句块之间是并行执行的(当其有效时),在同一语句块中的子语句块相互间也是并行执行的。
当这两个 always 语句响应的敏感信号都发生变化时,两个always语句是并行执行的。