Lattice、Xilinx FPGA reg初始化赋值问题

一、起因

最近在开发Lattice的一款低功耗FPGA时,遇到了reg初始化复位问题,经过在网上搜寻相关资料整理如下;

二、FPGA中reg的初始化方式

  1. 在定义时初始化,例如:
    reg r_test = 1'b1;

  2. 在复位语句中,对reg进行赋值,例如:

    reg r_test;
    always@(posedge sys_clk) begin
    if(~sys_rst_n) begin
    r_test <= 'b0;
    end
    else begin
    //logic
    end
    end

  3. initial语句初始化
    很多人认为initial语句只可以用于仿真中,不可以被综合,实际上initial语句是可以被综合的(至少在vivado中可以),比如:

    reg r_test;
    initial begin
    r_test = 'b0;
    end

三、问题

以上三种方式在Xilinx FPGA中都可以成功的对reg初始化,但是在Lattice的ICE5LP4K中,赋值方式1似乎不同,例如以下代码:

     reg             [15:0]              r_ADC_READ_NUM          = 16'd64        ;
    always @ (posedge SYS_CLK ) begin
        if( r_CMD_VALID)begin
            r_TX_BUF_RCNT	<= r_ADC_READ_NUM;
        end else if(r_TX_BUF_REN)begin
            r_TX_BUF_RCNT	<= r_TX_BUF_RCNT - 1'b1 ;
        end
        //  r_TX_BUF_RCNT_DONE	<= r_TX_BUF_RCNT == 10'd0? 1'b1 : 1'b0 ;

        r_TX_BUF_PRE	<= {r_TX_BUF_PRE[14:0] , r_CMD_VALID };
        r_TX_BUF_REN	<= r_QSPI_TN & (r_TX_BUF_PRE[13] | r_QSPI_OFF_SEL==4'd0 & s_QSPI_CLK_UP ) & r_TX_BUF_RCNT>0 ;// MCU READ 128 Byte once
    end

虽然r_ADC_READ_NUM寄存器已经通过方式1进行了初始化,但是在上板测试中r_TX_BUF_REN一直不能被拉高,最后让我不得不怀疑上了r_TX_BUF_RCNT的数值,该寄存器在r_CMD_VALID时被赋值为r_ADC_READ_NUM,结果发现r_TX_BUF_RCNT一直为0,说明r_ADC_READ_NUM 并没有被初始化,对其进行复位初始化后,系统逻辑正常运行:

always @(posedge SYS_CLK or negedge sys_nRst) begin
    if(~sys_nRst) begin
        r_ADC_READ_NUM <= 16'd64; // initial value: default 64
    end
    else begin
    end
end

四、总结

对于xilinx FPGA中,赋值方式1可以正常工作,在lattice中不 work,因此,为了避免这种情况,建议养成复位赋值的方式对reg初始化,以确保FPGA上电后reg中的数据为一个我们设定的初值。