architecturesystem-veriloghdlbluespec

Bluespec Verilog - polymorphic vector type


In Bluespec System Verilog I would like to have a Vector of the same module but with different type parametrisations. I am trying to do something along the lines of this:

Module#(1) m1 <- mkModule;
Module#(2) m2 <- mkModule;
Module#(3) m3 <- mkModule;

Vector#(3, Module) v = cons(m1, cons(m2, cons(m3, nil)));

I have tried this

typedef union tagged {
    Module#(1) M1;
    Module#(2) M2; 
    Module#(3) M3;
} ModuleParametrisations deriving(Bits);

Module#(1) m1 <- mkModule;
Module#(2) m2 <- mkModule;
Module#(3) m3 <- mkModule;

Vector#(3, ModuleParametrisations) v = cons(M1(m1), cons(M2(m2), cons(M3(m3), nil)));

Which does compile but then there is awkwardness trying to call functions on these modules. I cannot just do v[0].func1() for example, type system doesn't like that. I would have to make a case statement it seems. This is a fairly straightforward thing that should probably be possible, and likely is but I am unsure how to get around the type system to do this sort of parametrisation

If this isn't possible in BSV is anything similar possible? I pretty much just want something that can be iterated over which holds different versions of the same module with different parametrisations


Solution

  • If it is possible to move the parameterization to the module rather than the interface, try:

    typedef struct {} NumProxy #(numeric type n);
    // or for general, non-numeric types:
    // typedef struct {} Proxy #(type t);
    
    interface Module;
    // not parameterized with n anymore
    // could still be parameterized with other things,
    // but they must be given the same type to belong to the same Vector
    endinterface
    module mkModule#(NumProxy#(n) _unused) (Module);
      // ... use n as you would if it where a parameter of the Module interface
    endmodule
    
    NumProxy#(1) pxy1 = error("don't look inside a proxy");
    NumProxy#(2) pxy2 = error("don't look inside a proxy");
    NumProxy#(3) pxy3 = error("don't look inside a proxy");
    
    Module m1 <- mkModule(pxy1);
    Module m2 <- mkModule(pxy2);
    Module m3 <- mkModule(pxy3);
    
    Vector#(3, Module) v = cons(m1, cons(m2, cons(m3, nil)));
    
    

    (plus or minus typos ;))