1.8. Cross-Module Referencing (XMR) in HDL Code
You can use XMR to read from nets or write to a net in different hierarchies. XMR is helpful in debugging and verification, for example:
- Override or force any signal. For more information, refer to Using force Statements in HDL Code.
- Write cover points for functional coverage.
- Tap into any signal from anywhere in the entire design.
Consider the following hierarchy within the instance top of module a:
module a net x instance p of module b net x instance m of module d net x instance q of module c net x instance n of module e net x instance r of module b net x instance m of module d net x
In the above scenario, all modules consist of a net named x. By using full-path-based XMR, you can globally reference each net x anywhere within the hierarchy, as follows:
XMR starts with searching within the current module. Then, it hierarchically searches downwards through child instances. If XMR is unresolved, it searches one step above in the hierarchy (parent module) and hierarchically downwards. It keeps going further in the hierarchy until it gets resolved. To avoid unexpected behavior, Intel® recommends always using the hierarchy path where possible.
XMR Use Case Examples
XMR of Signals in Higher Modules from Lower Modules
In the following example, the signal d in the sub module is assigned to the value a from the top module:
module top (input a, input b, output c, output d); sub inst1 (.a(a), .b(b), .c(c), .d(d)); endmodule module sub (input a, input b, output c, output d); assign c = a & b; assign d = top.a; endmodule
XMR of Signals in Lower Modules from Higher Modules
In the following example, the sub module's value a assigns the output value d, given the complete path in the top module:
module top (input a, input b, output c, output d); sub inst1 (.a(a), .b(b), .c(c)); assign d = inst1.a; endmodule module sub (input a, input b, output c); assign c = a & b; endmodule
XMR of Signals in generate Block
Consider the following example with a generate block where you write the value to temp at the top module and read the out2 value from the top module:
module top (input [3:0] in1, in2, input clk, output [3:0] out1, out2); generate begin:blk1 sub inst (in1, clk, out1, temp); end:blk1 endgenerate //XMR read assign out2 = top.blk1.inst.temp; endmodule
XMR From Inside an always Block
Consider the following example of XMR of signals within the always_comb construct, where the output value d in the top module is assigned from the sub module value a:
module top (input logic a, input logic b, output logic c, output logic d); sub inst1 (.a(a), .b(b), .c(c)); always_comb d = inst1.a; endmodule module sub (input logic a, input logic b, output logic c); assign c = b & a; endmodule
Limitations of XMR
The following are some limitations of XMR in the Intel® Quartus® Prime software:
- XMR must be within the same design partition. For example, if there are partitions A and B, then in partition B, there cannot be any XMR to anything in partition A and vice versa.
Note: The same partition requirement applies for global signals that are specified in a package and can be used in any module.
- Multiple-driven nets are not supported. So, you cannot use XMR to drive a net already driven by another signal.
- You can use XMR only in Verilog, SystemVerilog, and VHDL. It does not work for Text Design File (TDF) or Block Design File (BDF).
Note: Intel® does not recommend using XMR on SystemVerilog interfaces since they are prone to errors.
- You cannot use XMR to refer to signals inside an Intel® FPGA IP core or a Signal Tap partition that is automatically created during synthesis.
Did you find the information on this page useful?