In verification activity, many times the requirement comes to choose
specific value of enum variable from command line in either randomization of
transaction class or configuring agent.
System Verilog provides support to pass value of variable of type
int/bit/logic/string from command line using $value$plusargs function but it
does not direct support to pass value of enum variable from command line.
In earlier version of UVM (uvm 1.1d and prior), we can achieve this by
passing string value from command line and manually converting it into enum by writing
code in TB.
Let’s go through example how we can achieve this,
-------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef enum {VAL0, VAL1, VAL2, VAL3, VAL4} val_e; | |
module top(); | |
val_e vt; | |
string str; | |
bit match; | |
initial begin | |
#5; | |
if ($value$plusargs("VAL_E=%0s", str)) begin | |
vt = vt.first(); | |
do begin | |
if (vt.name() == str) begin | |
`uvm_info("top", $sformatf("matching Value:%s", vt.name()), UVM_LOW) | |
match = 1; | |
break; | |
end | |
else begin | |
vt = vt.next(); | |
end | |
end while (vt.first() != vt); | |
if (match == 0) begin | |
`uvm_error("top", $sformatf("Wrong enum value passed from command line")) | |
end | |
else begin | |
match = 0; | |
end | |
end | |
else begin | |
`uvm_info("top", $sformatf("enum value not passed from command line"), UVM_LOW) | |
end | |
end | |
endmodule : top | |
//Simulation command: | |
// ./simv +VAL_E=VAL_2 | |
//Output: | |
// UVM_ERROR pass_enum_value_from_cmd_uvm1p1d.sv(24) @ 5: reporter [top] Wrong enum value passed from command line | |
//Simulation command: | |
// ./simv +VAL_E=VAL2 | |
//Output: | |
// UVM_INFO pass_enum_value_from_cmd_uvm1p1d.sv(14) @ 5: reporter [top] matching Value:VAL2 |
-------------------------------------------------------------------------
In UVM 1.2 provides inbuilt facility to convert string into enumerated
value.
In UVM 1.2 library contains uvm_enum_wrapper#(T) class and this class
contains from_name() function.
from_name() function try to convert any string passed as argument into enumerated
value.
If any matching enumerated value found then this function returns 1 else
it returns 0.
-------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static function bit from_name( | |
string name, // String which will be converted into enumerated value | |
ref T value // enumerated value | |
); |
-------------------------------------------------------------------------
Let’s go through example,
-------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef enum {VAL0, VAL1, VAL2, VAL3, VAL4} val_e; | |
typedef uvm_enum_wrapper#(val_e) uvm_vt; | |
module top(); | |
val_e vt; | |
string str; | |
initial begin | |
#5; | |
if ($value$plusargs("VAL_E=%0s", str)) begin | |
//`uvm_info("top", $sformatf("str get from command line:%s", str), UVM_LOW) | |
if(!(uvm_vt::from_name(str, vt) )) begin | |
`uvm_error("top", $sformatf("Wrong enum value passed from command line")) | |
end | |
else begin | |
`uvm_info("top", $sformatf("enum name:%s", vt.name()), UVM_LOW) | |
end | |
end | |
else begin | |
`uvm_info("top", $sformatf("enum value not passed from command line"), UVM_LOW) | |
end | |
end | |
endmodule : top | |
//Simulation command: | |
// ./simv +VAL_E=VAL_2 | |
//Output: | |
// UVM_ERROR pass_enum_value_from_cmd_uvm_1p2.sv(17) @ 5: reporter [top] Wrong enum value passed from command line | |
//Simulation command: | |
// ./simv +VAL_E=VAL2 | |
//Output: | |
// UVM_INFO pass_enum_value_from_cmd_uvm_1p2.sv(14) @ 5: reporter [top] enum name:VAL2 |
-------------------------------------------------------------------------
In above approach from_name() function can convert only one string at a
time.
Now think about scenario where to randomize variable of enum user wants
to select from multiple values. But above approach works fine only with one
string value.
UVM provides uvm_split_string() function which splits the
string based on a delimiter and returns a queue with sub string.
-------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function automatic void uvm_split_string ( | |
string str, // Actual string which users wants to split into substring | |
byte sep, // Delimeter | |
ref string values[$] // Reference queue of substring | |
); |
-------------------------------------------------------------------------
Now after getting queue of substring from uvm_split_string() function, user can pass one one element of substring queue to from_name() function
in some loop and convert it into enumerated value.
Let’s go through example to understand this better,
-------------------------------------------------------------------------
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
typedef enum {VAL0, VAL1, VAL2, VAL3, VAL4} val_e; | |
typedef uvm_enum_wrapper#(val_e) uvm_vt; | |
module top(); | |
val_e vt; | |
string str; | |
val_e vt_q[$]; | |
string str_q[$]; | |
initial begin | |
#5; | |
if ($value$plusargs("VAL_E=%0s", str)) begin | |
`uvm_info("top", $sformatf("str get from command line:%s", str), UVM_LOW) | |
uvm_split_string(str, ",", str_q); | |
foreach (str_q[i]) begin | |
`uvm_info("top", $sformatf("str_q[%0d]:%s", i, str_q[i]), UVM_LOW) | |
end | |
foreach (str_q[i]) begin | |
if(!(uvm_vt::from_name(str_q[i], vt) )) begin | |
`uvm_error("top", $sformatf("Wrong enum value passed from command line")) | |
end | |
else begin | |
`uvm_info("top", $sformatf("enum name:%s", vt.name()), UVM_LOW) | |
vt_q.push_back(vt); | |
end | |
end | |
`uvm_info("top", $sformatf("Number of enum passed from command line:%0d", vt_q.size()), UVM_LOW) | |
`uvm_info("top", $sformatf("enum queue:%p", vt_q), UVM_LOW) | |
end | |
else begin | |
`uvm_info("top", $sformatf("enum value not passed from command line"), UVM_LOW) | |
end | |
end | |
endmodule : top | |
//Simulation command: | |
// ./simv +VAL_E=VAL1,VAL4 | |
//Output: | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(13) @ 5: reporter [top] str get from command line:VAL1,VAL4 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(17) @ 5: reporter [top] str_q[0]:VAL1 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(17) @ 5: reporter [top] str_q[1]:VAL4 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(25) @ 5: reporter [top] enum name:VAL1 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(25) @ 5: reporter [top] enum name:VAL4 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(29) @ 5: reporter [top] Number of enum passed from command line:2 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(30) @ 5: reporter [top] enum queue:'{VAL1, VAL4} | |
//Simulation command: | |
// ./simv +VAL_E=VAL1,VAL5 | |
//Output: | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(13) @ 5: reporter [top] str get from command line:VAL1,VAL5 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(17) @ 5: reporter [top] str_q[0]:VAL1 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(17) @ 5: reporter [top] str_q[1]:VAL5 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(25) @ 5: reporter [top] enum name:VAL1 | |
// UVM_ERROR pass_multi_enum_from_cmd_uvm1p2.sv(22) @ 5: reporter [top] Wrong enum value passed from command line | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(29) @ 5: reporter [top] Number of enum passed from command line:1 | |
// UVM_INFO pass_multi_enum_from_cmd_uvm1p2.sv(30) @ 5: reporter [top] enum queue:'{VAL1} |
-------------------------------------------------------------------------
Reference:
I know this if off topic but I'm looking into starting my own blog and was curious what all is needed to get setup? I'm assuming having a blog like yours would cost a pretty penny? I'm not very web savvy so I'm not 100% positive. Any suggestions or advice would be greatly appreciated. waterjet cutting edmonton
ReplyDeleteI am really enjoying reading your well written articles. It looks like you spend a lot of effort and time on your blog. I have bookmarked it and I am looking forward to reading new articles. Keep up the good work.
ReplyDeletePhp projects with source code
Online examination system in php
Student management system in php
Php projects for students
Free source code for academic
Academic projects provider in nashik
Academic project free download
Very useful. Thank you.
ReplyDeleteIamlinkfeeder
ReplyDeleteIamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder
Iamlinkfeeder