How to use $readmemh correctly

2024/10/07

What?

$readmemh is a Verilog directive that allows you to initialize an array. In simulation, this directive behaves as a “read file into array”. In synthesis, this directive behaves as a repository of initial values for, say, block RAM.

While the purpose of the directive is documented every which way, the correct usage of the directive is woefully under-explained.

How to use it correctly

If you have a file in a directory say:

/some/directory/file.mem

then you must add it to your synthesis project by its entire path. This of course helps your tools locate the file.

However, when you want to use the file, you must refer to it by its base name only:

initial $readmemh("file.mem", data);

Note how in the above example, we have completely omitted the /some/directory/ path bit. I find this non-intuitive, but apparently this is how tools handle the directive.

Formats

Other, not very well documented constraints may be applicable. I have not verified all of them, so tread carefully here:

Some tools will report these errors, some will keep silent. It’s a complete clusterduck.

Being equipped with knowledge is the best antidote against losing time and nerves around these issues.