verilog中初值定義


在利用verilog進行開發時,往往需要對某些寄存器進行賦初值,下面根據筆者在設計中遇到的情況進行分析。

          例如下面是實現流水燈(4個led),代碼如下:

module ledrun (

 

    input   wire                clk,

    input   wire                rst_n,

   

    output  reg     [3:0]       led

 

);

 

    parameter  T_1s =            50_000_000;

   

    reg             [25:0]      cnt;

   

    always @ (posedge clk, negedge rst_n) begin

        if (rst_n == 0)

            cnt <= 0;

        else

            if (cnt < T_1s - 1)

                cnt <= cnt + 1'b1;

            else

                cnt <= 0;

    end

   

    wire    flag_1s = (cnt == T_1s - 1);

   

    always @ (posedge clk, negedge rst_n) begin

        if (rst_n == 0)

            led <= 4'b1110;

        else

            if (flag_1s)

                led <= {led[2:0],led[3]};

            else

                led <= led;

    end

   

endmodule

          在上述模塊中,利用復位基於了led寄存器初值,然后下板之后,板子能夠按照我們所設計的方式來進行工作。但是,注意到一個問題,初值怎么給的呢?我們下板之后並沒有按下復位按鍵。開發板上電時間已經足夠長了,上電復位電路早已經不能夠起到任何作用了。初值怎么來的呢?

          筆者記得在一片文章上在敘述配置FPGA時,共分為三個步驟,配置FPGA,初始化FPGA,FPGA正常工作。而初始化FPGA,就應該把這個初值賦值給led寄存器了,所以導致不復位也可以正常工作。

          如果把代碼改成以下模式呢?

   

    initial led = 4'b1110;

   

    always @ (posedge clk) begin

        if (flag_1s)

            led <= {led[2:0],led[3]};

        else

            led <= led;

    end

 

          initial語句到底能否被綜合呢?很多的網友說,initial語句只是在仿真時有用,只是為了給仿真一個初值,是不能綜合的。另外在讀文件時,也只是在綜合器綜合時,把文件值賦值給對應存儲器。但是把上述代碼,配置到開發板中,initial語句賦值的初值,是可以被配置到開發板中的,經過賦值不同的值,會有不同的流水燈。

        下面是在quartus 中的模板代碼中的說明。是可以利用下述模式進行賦初值的,VHDL中,大多都是用此方法進行賦初值的。initial語句和下面語句是等效的。

  // Scalar reg with initial value. If the variable has no assigned value,
  // Quartus Prime Integrated Synthesis will use the initial value. Integrated
  // Synthesis will also infer power-up conditions for registers and memories
  // from the initial value.
  reg <variable_name> = <initial_value>;

  

如果在寫verilog時,同時用復位賦初值,也用initial賦初值,那么綜合器就會報出警告,說明賦值重復,並且按照復位賦初值的方式進行。

   

    initial led = 4'b1110;

   

    always @ (posedge clk, negedge rst_n) begin

        if (rst_n == 0)

            led <= 4'b0001;

        else

            if (flag_1s)

                led <= {led[2:0],led[3]};

            else

                led <= led;

    end

  

Critical Warning (18061): Ignored Power-Up Level option on the following registers
Critical Warning (18010): Register led[0]~reg0 will power up to High
Critical Warning (18010): Register led[1]~reg0 will power up to Low
Critical Warning (18010): Register led[2]~reg0 will power up to Low
Critical Warning (18010): Register led[3]~reg0 will power up to Low

  所以,initial語句可以認為是一個可綜合語句,不單單用來仿真時使用。

 

  筆者水平有限,如果設計中,有什么不妥的地方,懇請大佬們指出來。

  歡迎加好友探討QQ(奮斗的小孩郝旭帥):746833924,QQ群:173560979。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM