Intel® Quartus® Prime Software
Intel® Quartus® Prime Design Software, Design Entry, Synthesis, Simulation, Verification, Timing Analysis, System Design (Platform Designer, formerly Qsys)
16597 Discussions

A question about parameterized structure between interface and module

Altera_Forum
Honored Contributor II
2,327 Views

Hello everyone! 

I have a design that is using client/server architecture, one server module polling multiple client module periodically to check if the client module needs update, and if the client which is been polled needs update, then server retrieve some information and feedback datas depending on the retrieved information. 

Normally I can define a packed structure type to transmit the information from client to server, to simplify the port codes of server module and client module, just like this: 

typedef struct packed { logic sig1; logic sig2; } client_info_t; module server( ... input client_info_t client_info, ... ); ... endmodule module client( ... output client_info_t client_info, ... ); ... endmodule  

But, when the server and client module are designed as parameterized module, and the bitwidth of structure's elements is depend on the instantiating parameter of client or server module, or both of them, the question is coming: 

How can I pass the instantiating parameter from module to the structure? 

The following example code can demonstrate more clearly what puzzles me: 

typedef struct packed { logic sig1; logic sig2; // BITWIDTH_OF_SIG2 is the parameter that should be passed from client or server module. } client_info_t; module server# ( parameter BITWIDTH_OF_SIG2 = 3 // BITWIDTH_OF_SIG2 should be passed to the structure which is the part of module port. ) ( ... input client_info_t client_info, ... ); ... endmodule module client# ( parameter BIT_WIDTH_OF_SIG2 = 3 // BITWIDTH_OF_SIG2 should be passed to the structure which is the part of module port. ) ( ... output client_info_t client_info, ... ); ... endmodule  

Although I can split the structure and define multiple port connections for each element, but this method will significantly increase the complexity of module port', and that is not what I want. So, is there any better solution about it?
0 Kudos
4 Replies
Altera_Forum
Honored Contributor II
850 Views

The only option here is to separate the ports as you suggest, as Verilog does now allow what you suggest. 

In VHDL 2008, you can do this as you can define records with unconstrained data structures that are constrained when they are used, and this is supported in quartus.
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

This is exactly what a SystemVerilog interface is for. 

 

 

interface# (int BITWIDTH_OF_SIG2) client_interface; typedef struct packed { logic sig1; logic sig2; // BITWIDTH_OF_SIG2 is the parameter that should be passed from client or server module. } client_info_t; client_info_t info; modport client(output info); modport server(input info); endinterface module server_module ( ... client_interface.server client_port, ... ); ... // access client_port.info as an input endmodule module client_module ( ... client_interface.client client_port, ... ); // ... // access client_port.info as an output endmoduleThere is no longer a need to parameterize the client and sever modules. If they need it they can access it throu client_port.BITWIDTH_OF_SIG
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

 

--- Quote Start ---  

The only option here is to separate the ports as you suggest, as Verilog does now allow what you suggest. 

In VHDL 2008, you can do this as you can define records with unconstrained data structures that are constrained when they are used, and this is supported in quartus. 

--- Quote End ---  

 

Hi, Mr.Tricky. 

Thanks for your suggestion. The VHDL is quite a different language to verilog, and seems even more strange. I must take some more time to learn it.  

Even though, you gave me another choice for my question, thanks again!
0 Kudos
Altera_Forum
Honored Contributor II
850 Views

 

--- Quote Start ---  

This is exactly what a SystemVerilog interface is for. 

 

 

interface# (int BITWIDTH_OF_SIG2) client_interface; typedef struct packed { logic sig1; logic sig2; // BITWIDTH_OF_SIG2 is the parameter that should be passed from client or server module. } client_info_t; client_info_t info; modport client(output info); modport server(input info); endinterface module server_module ( ... client_interface.server client_port, ... ); ... // access client_port.info as an input endmodule module client_module ( ... client_interface.client client_port, ... ); // ... // access client_port.info as an output endmoduleThere is no longer a need to parameterize the client and sever modules. If they need it they can access it throu client_port.BITWIDTH_OF_SIG 

--- Quote End ---  

 

 

Hi, Mr.dave_59! 

Thank you for your patient replying! and I‘m so sorry about replying you much later! 

Indeed, I'm using 'interface' in my design, but the problem is a little more complex. 

The parameter which is used to parameterize the structure is generated as a localparam in client_module depends on some conditions and checkings (for I want to simplify the user interface of client_module by doing some automatic work), I want to pass it automatically by client_module's port list to the interface and server_module, just like this: 

interface client_interface typedef struct packed { logic sig1; logic sig2; // BITWIDTH_OF_SIG2 is the parameter that should be passed from client or server module. } client_info_t; // modport client(output info); // I can't declare a modport for client_module, for there are multiple clients which will link to server. I think the modport should only be able to transmit ONE set of info generated by ONE client. modport server(input info); endinterface module server_module( ... client_interface.server client_port, ... ); ... // access client_port.info as an input endmodule module client_module# (parameter SOME_CONDITION_DEFINED_BY_USER) ( ... output client_info_t info, ... ); localparam VALOF_BITWIDTH_OF_SIG2 = SOME_CONDITION_DEFINED_BY_USER == 1 ? 32 : 16; endmodule  

Just as metioned above, for I want to link multiple clients to server, but I don't know how to transmit infoes from multiple clients to interface by a modport declared for client, I have to output the info from a port of client_module, instead of using modport for client, AND, I don't know how to reference a structure type defined in interface in client_module's port list. So I can't find any way to pass the 'VALOF_BITWIDTH_OF_SIG2' automatically. 

Even though the parameter declared at interface can instantiate the structure type, I don't know how to reference that structure type in client_module's port list, for the type is defined in interface, not global. If there was a way to implement, my problem could be resolved. 

So I thought if I could use parameterized structure, I could define the structure type in global range, and pass the 'VALOF_BITWIDTH_OF_SIG2' to that structure to meet the instantiated parent’s requirements such as 'client_interface' or 'client_module' etc. If it works, I can declare a parameter in interface which can be assigned with a compatible value with the client_module, and use the structure type 'client_info_t' which is defined in interface and instantiated by that parameter in interface and client_module's port list. But it seems to be impossible for Verilog and SystemVerilog haven't support parameterized structure yet, just as mentioned by Mr.Tricky, who replied me just before your replying. 

So, would you like to give me any more suggestion?
0 Kudos
Reply