数字电路几乎全部由时序逻辑电路和组合逻辑电路构成,而这两者的最大的区别从实现上来看是是否由时钟来驱动。通过一般的搜索可以发现组合逻辑电路不具备记忆功能,当前的输出由当前的输入决定,而时序逻辑不仅由当前的输入决定,也与之前的数据相关,换句话说就是具有记忆功能。但是组合逻辑电路也是可以有记忆功能的,比如Latch,但是这种电路是强烈不推荐在可综合设计电路中出现,除非是特殊需求,一旦出现在跑lint或者综合工具时会报combinational loop的warning/error。
时序电路建模
always@(posedge clk or negedge rst_n) begin
if(!rst_n)
d <= 1'b0;
else
d <= a;
end
这段代码描述的电路就是在时钟上升沿的时候判采样a的数据(简单打拍);一般而言时序逻辑电路建模都要用非阻塞赋值(<=),这是一种基本的规范,如果在仿真电路中错误使用=与<=会导致一些意想不到的结果,比如采样不符合预期。
组合电路建模
//method 1
assign a = cond1 ? 1'b0 : (b & c);
//method 2
always@(*) begin
if(cond1)
a = 1'b0;
else if(b & c)
a = 1'b1;
else
a = 1'b0;
end
verilog中常用的组合逻辑电路描述方式为上面这两种,功能都是一样的,都要用阻塞赋值(=),因为组合逻辑电路有明显的先后执行的顺序关系(更多详细的内容可以另外再做搜寻学习)。只是第一种在声明a的类型时是wire,第二种是reg。另外在第二种方式中如果不写else就会产生上述的组合逻辑回环,导致latch的产生,所以在用if...else if ..结构或者case语句时一定要把所有的条件写全,case中最好写上default,当然如果前面已经把所有条件都遍历了就最好不要写,收集覆盖率的时候会覆盖不到。
基本上上面三种方式就能描述数字电路90%的内容了,简单来看就是由时钟驱动的寄存器电路就是时序逻辑电路,跟时钟无关的就是组合逻辑电路。