Using Verilog “initial” blocks for FPGA synthesis: Legit? Portable?

This post was written by eli on February 23, 2018
Posted Under: FPGA

Introduction

Ask an VLSI engineer if the Verilog “initial” keyword is legit for synthesis, and flames of fury will go your way. However in the FPGA world, it’s a portable way to assign registers and array with the initial (and possibly constant) values immediately after configuration.

The main argument against this practice is that a “real” reset should be used to set the initial values. This is a valid argument, in particular when the clock may be unstable after configuration is done. However it’s often desired to have some kind of reset-generating logic that kicks off immediately after configuration, and this way or another, it depends on the initial wakeup state. Which must be nailed down somehow.

So I made a little survey among the synthesis tools that are relevant for my own work, to verify that it’s safe to use “initial” for this purpose. The answer is yes, in short: The “initial” block is the portable way in Verilog. The references for this conclusion are given below.

Initializing registers

So, is this fine?

reg [7:0] myreg;
initial myreg = 12;
  • Xilinx XST: Yes. Table 7-26 simply says that “All Initial Blocks” are supported in the XST User Guide. An example for initialing an FSM’s state variable is given in “Finite State Machines Coding Examples”. Another example is given in “Specifying INIT Value for a Flip-Flop Coding Examples”. There are also examples of initializing an array by individually setting its entries in this guide.
  • Vivado: Yes, however not said explicitly in the UG901 User Guide. But given the examples showing how to initialize arrays with initial blocks, initializing plain registers go without saying (?).
  • Quartus: Yes. From Chapter 8 of Quartus II Handbook, volume I, Integrated Synthesis: “The software also synthesizes variables
    that are assigned values in Verilog HDL initial blocks into power-up conditions.”

Initializing an array

And what about this?

reg [3:0] mem[0:1023];
initial $readmemh("data.hex", mem);
  • Xilinx XST: Yes. The XST User Guide says in the section named “Verilog System Tasks and Functions Supported in XST”: “The $readmemb and $readmemh system tasks can be used to initialize block memories”. An example for this is given in the section named “Initializing RAM From an External File”.
  • Vivado: Yes. Xilinx’ User Guide UG901 in “Specifying RAM Initial Contents in an External Data File” shown an example.
  • Quartus: Yes. From Chapter 8 of Quartus II Handbook, volume I, Integrated Synthesis: “Quartus II integrated synthesis supports the $readmemb and $readmemh system tasks to initialize memories”

Reader Comments

I tested it on Machxo3 with Lattice Synthesis engine, and it doesn’t work:

/* generate reset */
reg [3:0] resetcount;
wire reset = !resetcount[3];
wire resetn = resetcount[3];

initial resetcount = 4′b0;

always@(posedge clock)
if(reset)
resetcount = resetcount + 1;

No reset pulse are emitted :(

#1 
Written By Martoni on November 27th, 2018 @ 10:40

Add a Comment

required, use real name
required, will not be published
optional, your blog address