- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
Link Copied
4 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
endmodule
There 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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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!
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
--- 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
endmodule
There 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?
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page