一、always语句介绍

  module是一个模块的语法,或者说是一个电路模块的语法,然后FPGA代码中见的最多的应该就是alwsys语句了。

        到处都是alwsys,那么alwayls怎么意思呢?

        例如最常用的一句:

always @(posedge clk or negedge rst_n)

        关键字always就是一直的意思,就是上电后这个模块会一直运行下去。

        @是探测变化的意思,就是小括号内的信号只要安装规定的动作变化就能被探测到。

        小括号的内容就是该模块运行的条件,

        关键字posedge是取上升沿的意思,posedge clk就是clk这个信号的上升沿是触发条件;negedge就是取下降沿的意思,negedge rst_n就是rst_n这个信号的下降沿是触发条件;or就是posedge clk和negedge rst_n这两个条件有一个达到这个模块就会运行。

        于是乎,FPGA代码阅读就变得特别简单了。。。

always @(posedge clk or negedge rst_n) 
begin
    if (!rst_n) 
        begin 
            q <= 1'b0;
        end 
    else 
        begin 
            q <= d; 
        end
end

        

二、FPGA 编码的「黄金规范」

时序逻辑(生成寄存器)

  1. 一个 always 块对应一个时钟域 + 一组强关联的时序动作,可赋值多个信号,拒绝「一个信号一个 always 块」;
  2. 必须用非阻塞赋值<=,模拟硬件并行更新;
  3. 触发列表必须包含时钟沿,异步复位需加复位沿,同步复位仅加时钟沿;
  4. 寄存器的更新 / 复位仅在触发沿到来时发生,非触发沿保持原值。

组合逻辑(无寄存器)

  1. 一个 always 块对应一个独立的组合逻辑功能,可赋值多个相关输出;
  2. 必须用阻塞赋值=,模拟硬件实时连线;
  3. 触发列表用always @(*)(自动敏感列表),避免漏写输入导致的综合毛刺。

通用规则

  1. 不同时钟域、不同复位方式的逻辑,必须分开写 always 块;
  2. 寄存器信号必须在 always 块内赋值,且只能在一个 always 块内赋值(多驱动会导致硬件冲突,综合报错);
  3. 所有寄存器必须有复位值(避免上电后状态未知,FPGA 设计的硬性要求)。

更多推荐