1、Verilog HDL语言过程中关于三种常用赋值语句
“=”阻塞赋值语句,相当于串行语句,即所有该类型语句在所在模块内按顺序执行。常用于组合逻辑。
“<=”非阻塞赋值语句,相当于并行语句,当该语句所在模块结束时,所有带“<=”的语句同时执行。常用于时序逻辑(寄存器 ).
2、inout outpunt inout 等本身默认都是wire类型,但是要在initial和always语句下操作,必须申明为reg类型。
3、在编写测试文件时,输入信号定义为reg类型,输出信号定义为wire类型。这个要谨记。
4、if-else语句如果有if下有多条语句,需要加入begin end。
eg: if(!rst)
begin
clk_out=1'b0;
count=0;
end
5、
组合逻辑电路的设计,在谈到always电平敏感信号列表时,网上有的说:
“ 在赋值表达式右端参与赋值的所有信号都必须在always @(敏感电平列表)中列出,always中if语句的判断表达式必须在敏感电平列表中列出。如果在赋值表达式右端引用了敏感电平列表中没有列出的信号,在综合时将会为没有列出的信号隐含地产生一个透明锁存器。这是因为该信号的变化不会立刻引起所赋值的变化,而必须等到敏感电平列表中的某一个信号变化时,它的作用才表现出来,即相当于存在一个透明锁存器,把该信号的变化暂存起来,待敏感电平列表中的某一个信号变化时再起作用,纯组合逻辑电路不可能作到这一点。综合器会发出警告。”
这句话是错的!而事实的真相应该是这段话:
“敏感信号列表出现在always块中,其典型行为级的含义为:只要敏感信号列表内的信号发生电平变化,则always模块中的语句就执行一次,因此设计人员必须将所有的输入信号和条件判断信号都列在信号列表中。有时不完整的信号列表会造成不同的仿真和综合结果,因此需要保证敏感信号的完备性。在实际的PLD 器件开发中,EDA 工具都会默认将所有的输入信号和条件判断语句作为触发信号,增减敏感信号列表中的信号不会对最终的执行结果产生影响,因此如果期望在设计中通过修改敏感信号来得到不同的逻辑,那就大错特错了。当敏感信号不完备时,会使得仿真结果不一样,这是因为仿真器在工作时不会自动补充敏感信号表。如果缺少信号,则无法触发和该信号相关的仿真进程,也就得不到正确的仿真结果。”
必须将所有的输入信号和条件判断信号都列在信号列表中
有一种输入方式是:
always@(*)
begin
....
end
另附分频及调用模块的程序.
div.v //4000000HZ分频到1HZ
module div(clk_in,clk_out); input clk_in; output clk_out; reg[31:0]count; parameter div_num=40000000-1; always @(posedge clk_in) begin if(count==div_num) count<=0; else count<=count+1; end reg clk_out; always @(posedge clk_in) begin if(count==div_num) clk_out<=~clk_out; end endmodule
test.v//调用并简单使用led
`include "div.v" module test(clk_in,led,out); input clk_in; output led; output out; wire clk_out; div u1( .clk_in(clk_in), .clk_out(clk_out) ); reg led; assign out=clk_out; always @(posedge clk_out) begin led<=~led; end endmodule
测试函数 led.v
`timescale 1ns/100ps module led_tb; reg clk_in; wire led; wire out; test u1( .clk_in(clk_in), .led(led), .out(out) ); initial begin clk_in<=0; forever #2 clk_in=~clk_in; end initial begin #8000 $stop; end initial $monitor($time,"clk=%d,led=%d",clk_in,led); endmodule