cocotb: Infinite loop during design discovery when instant name and generate inside module have the same name

Hi,

I’m trying to make a checkpoint module to dump and load simulation state. I’m building my work based on this example that @themperek mentioned: https://github.com/themperek/apbi2c_cocotb_example/blob/parallel/tb/checkpoint.py

This is the base of my code, and then I use a collections.deque to iterate over all objects in a non-iterative way.

sims = set ()
for sim in dut._handle.iterate(simulator.OBJECTS):
        sim_type  = sim.get_type()
        sim_name  = sim.get_name_string().split(".")[-1]  # this seems to be some bug
        # first layer full_name is same as sim_name
        if (sim_type in [simulator.REG, simulator.NET, simulator.MODULE, simulator.NETARRAY, simulator.GENARRAY]) and (sim_name not in sims):
            to_process.append((dut, sim, sim_type, sim_name, sim_name, ""))
            sims.add(sim_name)
    
while (to_process):
        entity, sim, sim_type, sim_name, full_name, path = to_process.popleft()
        hdl = SimHandle(sim, entity._path + "." + sim_name)

        if (sim_type == simulator.REG) or (sim_type == simulator.NET):
                checkpoint_hier[full_name] = hdl.value 
        else:
             if sim_type == simulator.MODULE:
                in_path = full_name
            else:
                in_path = path

            childs = set ()
            for child in hdl._handle.iterate(simulator.OBJECTS):
                    ...

I noticed in one of the modules the instant name had the same name as a generate block inside that module (inside the module that is instantiated). This caused the search process to get into a loop situation: XXX.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs.csr_reg_nregs

and number of csr_reg_nregs increases in each iteration. The entity._path + "." + sim_name doesn’t have the instant name inside the string, and generate blocks have a separate type (GENARRAY) where that has a child with the name of the generate. (I know it’s super confusing, I was confused myself too.) I think that this is causing this issue. Not sure this is Icarus bug, or the way SimHandle works.

For now I changed the generate name to make things work, but I think it would be nice to find the bottom of this issue. Or if I should use other methods to do discovery please let me know.

Moein

About this issue

  • Original URL
  • State: open
  • Created 4 years ago
  • Comments: 20 (10 by maintainers)

Most upvoted comments

I looked into this, and it’s completely cocotb’s fault: https://github.com/cocotb/cocotb/blob/dc6ad51ebb387d36ed78389d7971717ab9935ec7/cocotb/share/lib/vpi/VpiImpl.cpp#L237-L248 We rely on the gen scope array name (gen scope prefix) not matching the parent name. We essentially throw away the knowledge that we want a pseudo-region and attempt to recover it by only matching the names.

So a named generate this_name inside a module instantiation this_name breaks, and we create a GPI_MODULE instead of a GPI_GENARRAY. We add this new GPI_MODULE handle as a sub-handle to itself. Then iteration over the sub-handle repeats this, forever.