【HDLBits刷题】【Procedures】Always if2

A common source of errors: How to avoid making latches

When designing circuits, you must think first in terms of circuits:

  • I want this logic gate
  • I want a combinational blob of logic that has these inputs and produces these outputs
  • I want a combinational blob of logic followed by a set of flip-flops

What you must not do is write the code first, then hope it generates a proper circuit.

  • If (cpu_overheated) then shut_off_computer = 1;
  • If (~arrived) then keep_driving = ~gas_tank_empty;

Syntactically-correct code does not necessarily result in a reasonable circuit (combinational logic + flip-flops). The usual reason is: "What happens in the cases other than those you specified?". Verilog's answer is: Keep the outputs unchanged.

This behaviour of "keep outputs unchanged" means the current state needs to be remembered, and thus produces a latch. Combinational logic (e.g., logic gates) cannot remember any state. Watch out for Warning (10240): ... inferring latch(es)" messages. Unless the latch was intentional, it almost always indicates a bug. Combinational circuits must have a value assigned to all outputs under all conditions. This usually means you always need else clauses or a default value assigned to the outputs.

Demonstration

The following code contains incorrect behaviour that creates a latch. Fix the bugs so that you will shut off the computer only if it's really overheated, and stop driving if you've arrived at your destination or you need to refuel.

always @(*) begin
    if (cpu_overheated)
       shut_off_computer = 1;
end

always @(*) begin
    if (~arrived)
       keep_driving = ~gas_tank_empty;
end
// synthesis verilog_input_version verilog_2001
module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); //

    always @(*) begin
        if (cpu_overheated)
           shut_off_computer = 1;
        else
            shut_off_computer = 0;
    end
 
    always @(*) begin
        if (~arrived && ~gas_tank_empty)
           keep_driving = 1;
        else 
            keep_driving = 0;
    end

endmodule

一、锁存器是什么

       锁存器是一种在异步时序电路系统中,对输入信号电平敏感的单元,用来存储信息。一个锁存器可以存储1bit的信息,通常,锁存器会多个一起出现,如4位锁存器,8位锁存器。

        锁存器在数据未锁存时,输出端的信号随输入信号变化,就像信号通过一个缓冲器,一旦锁存信号有效,则数据被锁存,输入信号不起作用。因此,锁存器也被称为透明锁存器,指的是不锁存时输出对于输入是透明的。

二、锁存器与寄存器的区别:

        两者都是基本存储单元,单锁存器是电平触发的存储器,触发器是边沿触发的存储器。本质是,两者的基本功能是一样的,都可以存储数据。意思是说一个是组合逻辑的,一个是在时序电路中用的,时钟出发的。

 三、锁存器的危害:          

        对毛刺敏感,不能异步复位,所以上电以后处于不确定的状态;

        Latch会使静态时序分析变得非常复杂;

       在PLD芯片中,基本的单元是由查找表和触发器组成的,若生成锁存器反而需要更多的资源。

            第三条也是最基本的原因。

四、产生的原因  ********ps重重之重

      上面说了那没多只是觉得网上的没把锁存器说明白。下面的才是重点。

       1,case

       2,if-------else if

       3,always@(敏感信号表)

五、解决

      1.case——————加default:

      关于defalut的情况:一是可以 default:data=1‘bx;这个x表示未知,在综合时可以避免产生锁存器。在仿真时是红线表示。  二是   default:data=0;这样产生一个默认的情况。

       2.if-----------------------一定要有else语句。

      3.always---------如是说道:在赋值表达式右边参与赋值的信号都必须在always@(敏感电平列表)中列出。

如果在赋值表达式右端引用了敏感电平列表中没有列出的信号,那么在综合时,将会为该没有列出的信号隐含地产生一个透明锁存器。

     4. 付初值。好用的

六、怎么看到锁存器

    当然,ISE会对锁存提出警告。

       

一位网友指出:FPGA是一种基于查找表形式工作的,而锁存器相当于存在一个没有直接说明的状态,保持之前的值造成了锁存。

七、只要语句完整就不会有锁存器吗

    在很多情况下,我们希望某个值保值其原有值,既不一定是0,也不一定是1,只需要保持。比如下面代码:

 always @ (a or data_in)

    if(a) data_out=data_in;

    else data_out=data_out;

    这个时候if/else文件是完整,但是依然产生了锁存器,因为我们这个电路所描述的功能就是一个锁存器。其实语句不完整和else data_out=data_out;是一样的。在这里,我所希望的就是保持数值,但这种情况可以通过增加一个寄存器来保持,也不应该生成一个锁存器。

最后,锁存器只存在于组合电路中,在时序电路上是不存在的。

部分转载,侵删。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值