1. assign语句
assign语句是连续赋值语句,一般是将一个变量的值不间断的赋值给另一个变量,两个变量之间就类似于被导线连接在了一起,习惯上当做连线用。
assign语句的基本格式是:
assign a = b (逻辑运算符)c…;
assign语句的功能属于组合逻辑的范畴,应用主要为以下几项:
- 持续赋值
- 连线
- 对wire型变量赋值。wire是线网,相当于实际的连线。(如果用assign连接,就需使用wire型变量,wire型变量的值可以随时更新)
assign举例:
assign dac_wra = dac_clka; //将信号dac_clka与线dac_wra相连
assign dac_sleep = 0; //将dac_sleep对应的管脚接地
assign dac_mode = 1; //将dac_mode对应管脚固定接高电平
assign end_cnt0 = add_cnt0 && cnt0==2-1; //语句含义如下图
2. always语句
always语句是条件循环语句,执行机制是通过对一个名称为敏感变量表的事件驱动来实现。
always语句基本格式:
always @(敏感事件)begin
程序语句
end
always语句的意思是:当敏感事件的条件满足时,执行一次“程序语句”;敏感事件每满足一次,就执行“程序语句”一次(类似于C语言中的while循环)
2.1 always语句组合逻辑
组合逻辑含义:条件信号变化结果立刻变化
举例说明:每当信号a/信号b/信号d/信号sel发生变化时,就执行一次其内部语句。具体如下:
always @(a or b or d or sel)begin
if (sel==0)
c = a + b;
else
c = a + d;
end
当敏感信号非常多时,就会非常容易将某些敏感信号漏掉。为了避免这种情况可以将敏感变量表里面的所有条件信号用 “*” 代替(条件信号为a,b,d,sel;不包括c),具体如下:
always @(*)begin
if (sel==0)
c = a + b;
else
c = a + d;
end
2.2 always语句时序逻辑
示例一:
always @(posedge clk)begin
if (sel==0)
c <= a + b;
else
c <= a + d;
end
上述示例敏感列表是“posedge clk”,其中posedge表示上升沿。也就是说,当clk由0变成1的瞬间执行一次程序代码,其他时刻c的值保持不变。(如果clk没有由0变成1,即使a,b,d,sel发生变化,c的值也保持不变)
示例二:
always @(negedge clk)begin
if (sel==0)
c <= a + b;
else
c <= a + d;
end
上述示例敏感列表是“negedge clk”,其中negedge表示下降沿。也就是说,当clk由1变成0的瞬间执行一次程序代码,其他时刻c的值保持不变。(如果clk没有由1变成0,即使a,b,d,sel发生变化,c的值也保持不变)
示例三:
always @(posedge clk or negedge rst_n)begin
if (rst_n==1'b0)begin
c <= 0;
end
else if (sel==0)
c <= a + b;
else
c <= a + d;
end
上述示例的敏感列表为“posedge clk or negedge rst_n”,也就是说,当clk由0变为1的瞬间,或rst_n由1变为0的瞬间,执行一次程序代码,其他时刻c的值保持不变。
这种信号边沿触发,即信号上升沿或下降沿才变化的always,被称为时序逻辑。
此时信号clk为时钟(识别信号是不是时钟不是看名称,而是看这个信号放在哪里,只有放在敏感列表并且是边沿触发的才是时钟)
此时信号rst_n为复位信号(同样不是看名字来判断复位信号,而是同样放在敏感列表中并且沿边沿触发;更关键的是“程序语句”首先判断了rst_n的值,这表示rst_n的优先级最高,一般都是用于复位)
Tip:如果您在阅读的过程中发现任何的错误,欢迎前来指正!!