I have successfully setup a Cocotb verification environment for my design, and I am happy the way it works for RTL (VHDL in my case).
My design is using generics, and I am retrieving the value of these generics in several places of the python code (mostly in the run_test and in the model), following the template:
my_generic = dut.GEN_NAME.value
Unfortunately, this is not working in the case of gate level simulation, since my synthesized design does not have generics anymore, and therefore dut.GEN_NAME.value does not exist.
Should I move all in the direction of getting the parameters/generics values from the simulation flow (makefile of Cocotb) ?
If so, what is the cleanest way to do so? Using env variable?
(Btw, I use Questa, even if I don't expect this aspect to be simulator dependent...)
Thanks for your help and your advices...
Passing the configuration to the Python Cocotb code might be possible, but it is error prone because you have to ensure that the same values are passed which have been used for synthesis.
Another solution is to have a configuration package for the top-level entity stored in a separate file, e.g., top_config.vhdl
with content:
library ieee;
use ieee.std_logic_1164.all;
package top_config is
constant AA : positive := 5;
constant BB : integer := 10;
end package top_config;
The constants defined here, are then used as the default values for the generics of the top-level entity or directly within the top-level entity.
The package can be parsed now via some Python code within the Cocotb testbench:
from re import compile as re_compile
constantRegExpStr = r"^\s*constant\s*" # keyword and spaces
constantRegExpStr += r"(?P<name>\w+)" # name fo constant
constantRegExpStr += r"\s*:\s*" # divider and spaces
constantRegExpStr += r"(?P<type>\w+)" # type name
constantRegExpStr += r"\s*:=\s*" # assignment and spaces
constantRegExpStr += r"(?P<value>[0-9]+)" # value
constantRegExpStr += r"\s*;" # end of statement
constantRegExp = re_compile(constantRegExpStr)
with open("top_config.vhdl") as f:
for line in f.readlines():
m = constantRegExp.match(line)
if m is not None:
print("constant '{0}' with value '{1}'".format(m.group('name'), m.group('value')))
Instead of printing the matches, you can add it to a dictionary or do something else.