Reputation: 1
my need is to use given hierarchy many times based on "lphy_duc_1cc0,lphy_duc_1cc1,lphy_duc_1cc3 .....etc difference will be in hierarchy is only cc number.
reg_block.dl_lphy_duc_1cc0.dl_lphy.dl_lphy_ti
reg_block.dl_lphy_duc_1cc1.dl_lphy.dl_lphy_ti
reg_block.dl_lphy_duc_1cc2.dl_lphy.dl_lphy_ti
reg_block.dl_lphy_duc_1cc3.dl_lphy.dl_lphy_ti
.
.
.
i tried using
string hierarchy = $sformatf("reg_block.dl_lphy_duc_1cc%0d.dl_lphy.dl_lphy_ti",cc_num));
cc_num i'm parsing as per my need. but i'm getting becoz actual hierarchy is not a string.
Upvotes: 0
Views: 1418
Reputation: 116
As you are using UVM RAL model ,uvm_reg_block provides find_block method which you can use for this. Input to this function is a string and it returns handle to intended block.
string hierarchy = $sformatf("dl_lphy_duc_1cc%0d",cc_num));
sub_blk=reg_block.find_block("hierarchy");
Then you need to cast sub_blk and use registers/block inside that.
Upvotes: 0
Reputation: 12384
There is no way of direct solving it in verilog syntax unless you list all xrefs manually. However, there are a few ways to work around it. Let's start with a simple example which demonstrates the initial problem:
module phy();
logic [3:0] sig;
endmodule // phy
module regs();
phy phy0(), phy1(), phy2();
endmodule // regs
module tb();
regs regs();
initial begin
$display("1.0> %b", regs.phy0.sig);
$display("1.1> %b", regs.phy1.sig);
$display("1.2> %b", regs.phy2.sig);
end
endmodule
Here you have to list $display one by one manually to access all instances of 'sig'. There is no way to put them in a loop. But you can simplify it a bit using text macros:
`define X(num) regs.phy``0.sig
initial begin
$display("2.0> %b", `X(0));
$display("2.1> %b", `X(1));
$display("2.2> %b", `X(2));
end
Still, there is no way to make a loop here.
The only possibility to do an algorithmic approach is to go outside of verilog and use PLI/vpi functions to access the values. Here is an example of involving such a function using 'dpi' interface.
import "DPI" function void display(int num);
initial begin
for (int i = 0; i < 3; i++)
display(i);
end
It requires a 'c' (or c++) code to handle the access. vip functions allows accessing verilog variable data by their names. So, this function can look like the following:
#include <string.h>
#include <vpi_user.h>
void display(int num) {
const char name[256];
snprintf(name, 256, "regs.phy%d.sig", num);
vpiHandle sig = vpi_handle_by_name(name, 0);
if (!sig) {
vpi_printf("Error: no such signal: %s\n", name);
return;
}
s_vpi_value value = {vpiIntVal};
vpi_get_value(sig, &value);
vpi_printf("3.%d> %x\n", num, value.value.integer);
}
And finally, there is a method of 'generate' blocks which is a part of verilog syntax, but it would require to rewrite instantiation code part and it is limited in in its use:
module regs();
phy phy[3](); // << new instantiation method of 3 instances.
endmodule // regs
module tb();
regs regs();
for(genvar i = 0; i < 3; i++) begin
initial $display("4.%d> %b", i, regs.phy[i].sig);
end
endmodule // tb
Here both, arrayed instantiation and access are part of the 'generate' domain of verilog and are solved at elaboration time, therefore no dynamic (run-time) varibles can be used here to solve instance indexes. Both instantiations and access have certain limitations, e.g., parameters of instances have to follow certain rules, order of execution of initial blocks and consequently $displays is not defined, and so on.
Upvotes: 0
Reputation: 359
Option 1:
Depends on what you want to do, you can maybe use HDL paths backdoor access via DPI/PLI interface:
https://www.chipverify.com/uvm/uvm-hdl-access-routines https://verificationacademy.com/verification-methodology-reference/uvm/docs_1.2/html/files/dpi/uvm_hdl-svh.html
Specifically examine uvm_hdl_force
/uvm_hdl_read
/uvm_hdl_deposit
.
All functions accept strings as argument, so you just need to use your $sformatf()
result as an input to the functions.
Maybe something like this:
int rdata;
uvm_hdl_read($sformatf("reg_block.dl_lphy_duc_1cc%0d.dl_lphy.dl_lphy_ti",cc_num), rdata));
Option 2:
Instead of using strings, you can define text macros for all such variations. But this is not a good and methodological way IMO, since I believe you have a lot of such paths, and you probably must have some indexing capability.
Option 3:
Another option which might work for you, is using the VPI interface, which has capability to access strings as paths. There is some information in the next links:
SystemVerilog: String to Circuit Net
https://en.wikipedia.org/wiki/Verilog_Procedural_Interface
I am not experienced with it, but a quick search online gives some verification forums examples.
Option 4:
One last option, is to convert the HDL paths to array of units.
i.e., instead of instantiating dl_lphy_duc_1cc0, dl_lphy_duc_1cc1, etc., instantiate a single unit, but use array instatiation:
https://besubjects.wordpress.com/2016/08/13/array-of-instances-of-primitives/
Something like:
dl_lphy_duc_1cc #(
...
) dl_lphy_duc_1cc[NUM_OF_CC-1:0] (
...
);
which will give you the next HDL path (or similar path with indexing capability):
reg_block.dl_lphy_duc_1cc[*].dl_lphy.dl_lphy_ti
You can then just access it using index, no need for strings:
reg_block.dl_lphy_duc_1cc[cc_num].dl_lphy.dl_lphy_ti
IMO this is the most methodological and correct option to use. But, it may not be feasible at all in case you can't control the HDL path structure (e.g., 3rd party IP code which you can't change).
Upvotes: 0