锁存器与触发器 & 阻塞赋值与非阻塞赋值
1. 锁存器与触发器
锁存器latch:电平触发
寄存器flip-flop:边沿触发
寄存器:用来存放数据的一些小型存储区域,由多个触发器组成(时钟端连在一起)
触发器与锁存器优缺点:
- latch由电平控制,非同步控制;ff是时钟边沿触发,可以同步控制;
- latch 对输入电平敏感,受布线延迟影响较大,很难保证输出没有毛刺产生;DFF 则不易产生毛刺。
- latch面积资源消耗少
- latch 的静态时序分析会变得比较复杂
触发器verilog(非阻塞赋值)
always @ (posedge clk) begin q<=d; end
触发器verilog(非阻塞赋值)
always @ (*) always@(en,d) if(clk) out_q <= in_d; or if(en = = 1’b1) q<=d; else out_q <= out_q;
组合逻辑中,如果if没有else;case没有default,都会导致数据保留原值,形成Latch
那为什么锁存器要用非阻塞赋值?
module D_latch_behavior (input D, input Enable, output Q, output Qbar); always @ (D or Enable) if(Enable) begin Q <= D; Qbar <= ~D; end endmodule
Note that the non-blokcing assignment operator (<=) is used instead of blocking (=) operator which had been used in dataflow modeling
2. 阻塞赋值与非阻塞赋值
阻塞(blocking)赋值方式(如 b=a)
“=”左右的逻辑是用线连接,一般用在组合逻辑
①赋值语句立即执行,执行完毕后才执行下一条语句(即为阻塞的含义,依次顺序执行);
②b的值在赋值语句执行完后立即改变。
Example:
always @(posedge clk) begin b = a; c = b; end
clk信号的上升沿到来时,b马上取a的值,执行完毕后c取b的值(即等于a)
非阻塞(Non_blocking)赋值方式(如 b <= a)
“<=”左右使用触发器连接,一般用在时序逻辑和Latch建模
①语句执行到此时,先计算“<=”右侧a的值,但不立即赋值给b;
②always块结束后才完成此次赋值操作;
Example:
always @(posedge clk) begin b <= a; c <= b; end
clk信号的上升沿到来时,“<=”号右侧的a、b值先计算,等always块结束后,b就等于a,而c等于刚才计算的b(即原来的b值) ,这里生成了2个寄存器。“b <= a”和“c <= b”在posedge_clk处类似于“并发执行”。