Verilog序列检测问题

请教一下为什么上板子时,我把计数那段雨具单独写一个always块,res就一直为0,根本没计数。如下:

module detect(
    input clk,
    input rst,
    input[15:1] SW,
    output reg[2:0] res
);

    reg[2:0] tmp;
    reg[15:1] sec;

    //初始化
     always @(posedge clk) begin
        if(!rst) begin
            tmp=3'b000;
            res=3'b0;
            sec=SW;
            end
        else if(sec>0) begin
            tmp={tmp[1:0],sec[15]};
            sec=sec<<1;
            end
        else  tmp=3'b0;
    end
    
    //计数
    always @(posedge clk) begin
        if(tmp==3'b101) begin
            res=res+1;
            tmp=3'b000;
        end
    end
endmodule

但是我把他放进第一个always块中,就能计数了,请问这是为什么呀?

module detect(
    input clk,
    input rst,
    input[15:1] SW,
    output reg[2:0] res
);

    reg[2:0] tmp;
    reg[15:1] sec;

    //初始化
     always @(posedge clk) begin
        if(!rst) begin
            tmp=3'b000;
            res=3'b0;
            sec=SW;
            end
        else if(sec>0) begin
            tmp={tmp[1:0],sec[15]};
            sec=sec<<1;
            if(tmp==3'b101) begin
              res=res+1;
              tmp=3'b000;
            end
            end
        else  tmp=3'b0;
    end
    
    
endmodule

res 和 tmp 这两个变量必须在同一个always 中赋值。
verilog 是个描述硬件电路的语言。当这俩变量在多个always 中赋值,相当于多个芯片的输出连在一起短路了。

  • 帮你找了个相似的问题, 你可以看下: https://ask.csdn.net/questions/7742980
  • 除此之外, 这篇博客: 01.高质量的Verilog描述方法中的 三、电路设计需要注意的基本事项 部分也许能够解决你的问题, 你可以仔细阅读以下内容或跳转源博客中阅读:
    1. 慎用 latch。逻辑综合工具很难解释 latch,因此,除非特殊用途,一般避免引入 latch。

    image-20220304201738458

    image-20220304202542498

    1. 易引入 latch 的途径,一般是使用不完备的条件判断语句。防止产生非目的性 Latch 的措施主要有:使用完备的 if…else 语句;为每个输入条件设计输出操作,为 case 语句设置 default 操作;仔细检查综合器生成的报告,latch 会以 warning 的形式报告。

    image-20220304202640259

    image-20220304202942054

    image-20220304203015928

    image-20220304203125855

    image-20220304203200800

    1. 在电路设计的过程中,如果发现某个电路的负载比较多,则可以通过逻辑复制,降低关键信号的扇出,进而降低该信号的传播延迟,提高电路性能。

    image-20220304203246431

    1. 如果我们发现电路中存在较多的公共单元,也可以通过资源共享的方式,减小面积。但是,一般来说,共享会导致性能下降,所以还要根据性能和面积进行取舍。

    image-20220304203410260

    1. 在设计电路的时候,我们也可以根据数据的延迟,对这些资源进行顺序重排,降低传播延迟。如图所示,A 信号到来比较晚,我们就可以把它尽可能放到后面,隐藏其延迟。

    image-20220304204539918

    1. 最后一个小建议。在代码书写过程中,尽可能使用 always 描述电路,assign 仅仅用来连线。少用:?这种形式,因为这种形式通常难以阅读,且多层嵌套后很难被综合器解释。

    image-20220304204640541

    1. 所有的组合逻辑或锁存的 always 结构必须有敏感信号列表。这个敏感信号列表必须包含所有的输入信号。综合过程将产生一个取决于除敏感列表中所有其它值的结构,它将可能在行为仿真和门级仿真见产生潜在的失配。
    2. 在综合过程中,每个 Verilog always 块敏感信号列表只能对应一个时钟。原因:这是将每一个过程限制在单一寄存器类型的要求,有利于逻辑综合和静态时序分析。
    3. 不允许 Wait 声明和# delay 声明。Wait 声明语句,不论是清楚还是含糊,都不能用于可综合设计。从 RTL 级转换到 gate 级的综合工具一般都不支持 Wait 声明和# delay 声明,为了有效的综合,这些语句应该避免。在不需要进行综合的行为模块中,如测试模块、表示行为的虚拟器件模块中可以使用。
    4. 在时序电路中必须使用非阻塞赋值(<=),组合逻辑电路必须使用阻塞赋值(=),这个一定要注意,严格按这个要求写。
    5. 分开异步逻辑与同步逻辑。避免综合和静态时序时碰到问题,简化约束和编码难度。
    6. 不可应用于非综合模块中(例如:总线模块,总线监视器或是模拟模块)除非他们被设计来综合仿真。
    7. 分开控制逻辑和存储器,建议控制逻辑和存储器逻辑分成独立的模块。通常来说,存储器是用 memory compiler 生成的,其综合方式与 RTL 代码不同,所以混在一起,不利用综合,不利于很方便地更换工艺库和平台。