1
votes

I'm pretty sure there is no way to do what I am trying, but just in case there is an interesting clever solution, I thought I'd ask around. I have a parameterized SystemVerilog interface, inside of which I am generating modports

interface some_interface #(parameter NUM_READERS=3);

    logic [`kBitsPerProgramCounter-1:0] read_addr[NUM_READERS];
    logic [`kBitsPerProgramCounter-1:0] write_addr; 

    genvar i;
    generate
        // generates Reader[n].Modport
        for (i = 0; i < NUM_READERS; ++i) begin : Reader
            modport Modport
            (
                output .read_addr(read_addr[i])
            );
        end
    endgenerate

endinterface

Using this is easy if I have different module types taking different modports. However, what I wanted to try doing is to have multiple instances of the same module. I tried this by parameterizing on type

module some_block#(parameter type SOMETYPE) (
    input logic CLK200MHZ,
    SOMETYPE aarrgghh);

But getting it to work syntactically has been challenging. Giving SOMETYPE a default value doesn't work because Vivado complains about not allowing hierarchical types, so right off the bat I don't think this will work. When instantiating, I tried using the full modport name, the full modport name with the instantiated interface, and a few others, but nothing seems to work.

So I am curious if there is a clever way I can have multiple instantiations of some_block, each taking a different generated modport. And if not, is there some fun clever trick I can do to use the generated modports? The idea in the first place was that I have a thing that has one writer and multiple readers. I wanted to generate a modport for each reader so that it could only touch it's own read address. I guess I could always just parameterize some_block on an integer, pass some_block the whole interface, and then rely on some_block to only touch the read address corresponding to the passed in integer, but that might be error prone.

1
non of the major simlulators support modports in generate blocks. do you really have a compilable example? - Serge
seems to work fine for me. I can generate the modports, the simulator doesn't complain, and I can see all the members in the debugger see imgur.com/a/H02oBZj - okonomi

1 Answers

0
votes

Assuming that 'generate' works, there is nothing to be concerned about modules. There is no need to pass a type parameter. The module port is just supposed to be of the type of your interface.

module top();
   some_interface ifc;
   for (genvar gi = 0; gi < NUM_REASDERS; gi++) begin: inst
      some_block sb(ifc.Reader[gi].Modport);
   end
endmodule

module some_block (some_interface ifc);
    always_comb myvar = ifc.read_addr;

some_block just always references the 'read_addr' which is the modport var. You can use a generate block in the 'top' module.