Specman - how can I use define exp as string in macro? - macros

I have the following define (and more):
define d_buff1_en_adc0_s 'LV_TOP_TB/LV_TOP_inst//CAFE_MPW_TOP_inst/D_BUFF1_en_ADC0';
I have the following macro:
define <force_and_check'action> "force_and_check <signal_f'exp> <signal_c'exp> <ip_name'exp> <val_signal_f'num> <init_val_signal_f'num>" as {
force <signal_f'exp> = <val_signal_f'num>;
wait[2];
check that <signal_c'exp>_s == <val_signal_f'num> else dut_errorf("%s Connectivity Error! %s is %b, but should be %b" ,<ip_name'exp>, **<signal_c'exp>**, <signal_c'exp>_s, <val_signal_f'num>);
force <signal_f'exp> = <init_val_signal_f'num>;
};
Example of using the macro:
force_and_check 'adc_s_event[4]' d_buff1_en_adc0_s "CAFE" 1'b1 1'b0;
I want to present the (the bold one ** **) int the dut_errorf as string (for eample as d_buff1_en_adc0_s)... How can I do it? (not it present as the value of the define in hexa)

Just put it inside double quotes as part of the string:
check that <signal_c'exp>_s == <val_signal_f'num>
else dut_errorf("%s Connectivity Error! <signal_c'exp> is %b, but should be %b", <ip_name'exp>, <signal_c'exp>_s, <val_signal_f'num>);

Related

How to open a website using AutohotKey that contains special characters "%" in the url itself?

I want to open this website with this line of code:
Run,https://logowanie.uek.krakow.pl/cas/login?service=https%3A%2F%2Fe-uczelnia.uek.krakow.pl%2Flogin%2Findex.php%3FauthCAS%3DCAS
When i try to run this line I get this error:
The following variable name contains an illegal character:
'2Fe-uczelnia-uek.krakow.pl'
The program will exit.
Im pretty sure that "%" is the issue.
You dont need to encode URL while using Run command.
Run,https://logowanie.uek.krakow.pl/cas/login?service=https://e-uczelnia.uek.krakow.pl/login/index.php?authCAS=CAS
But if you really need or want to encode, you may try this function:
str := "hello%20world"
MsgBox, % decoded := EncodeDecodeURI(str, false)
MsgBox, % EncodeDecodeURI(decoded)
EncodeDecodeURI(str, encode := true, component := true) {
static Doc, JS
if !Doc {
Doc := ComObjCreate("htmlfile")
Doc.write("<meta http-equiv=""X-UA-Compatible"" content=""IE=9"">")
JS := Doc.parentWindow
( Doc.documentMode < 9 && JS.execScript() )
}
Return JS[ (encode ? "en" : "de") . "codeURI" . (component ? "Component" : "") ](str)
}
Source: https://www.autohotkey.com/boards/viewtopic.php?t=84825
You want to ditch the usage of legacy syntax, and enter the modern expression syntax by specifying a single % at the start of that parameter.
Then you can explicitly specify a string with "":
Run, % "https://logowanie.uek.krakow.pl/cas/login?service=https%3A%2F%2Fe-uczelnia.uek.krakow.pl%2Flogin%2Findex.php%3FauthCAS%3DCAS"
If you for some reason were to want to use the legacy syntax, (there is no valid reason to do so), you'd want to escape the %s with a `.

Pre-compile textual replacement macro with arguments

I am trying to create some kind of a dut_error wrapper. Something that will take some arguments and construct them in a specific way to a dut_error.
I can't use a method to replace the calls to dut_error because to my understanding after check that ... then ... else can only come a dut_error (or dut_errorf). And indeed if I try to do something like:
my_dut_error(arg1: string, arg2: string) is {
dut_error("first argument is ", arg, " and second argument is ", arg2);
};
check that FALSE else my_dut_error("check1", "check2");
I get an error:
*** Error: Unrecognized exp
[Unrecognized expression 'FALSE else my_dut_error("check1", "check2")']
at line x in main.e
check that FALSE else my_dut_error("check1", "check2");
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
So I thought about defining a macro to simply do a textual replace from my wrapper to an actual dut_error:
define <my_dut_error'exp> "my_dut_error(<arg1'name>, <arg2'name>)" as {
dut_error("first argument is ", <arg1'name>, " and second argument is ", <arg2'name>)
};
But got the same error.
Then I read about the preprocessor directive #define so tried:
#define my_dut_error(arg1, arg2) dut_error("first argument is ", arg, " and second argument is ", arg2)
But that just gave a syntax error.
How can I define a pre-compiled textual replacement macro that takes arguments, similar to C?
The reason I want to do that is to achieve some sort of an "interface" to the dut_error so all errors have a consistent structure. This way, different people writing different errors will only pass the arguments necessary by that interface and internally an appropriate message will be created.
not sure i understood what you want to do in the wrapper, but perhaps you can achieve what you want by using the dut_error_struct.
it has set of api, which you can use as hooks (do something when the error is caught) and to query about the specific error.
for example:
extend dut_error_struct {
pre_error() is also {
if source_method_name() == "post_generate" and
source_struct() is a BLUE packet {
out("\nProblem in generation? ", source_location());
// do something for error during generation
};
write() is first {
if get_mesage() ~ "AHB Error..." {
ahb_monitor::increase_errors();
};
};
};
dut_error accepts one parameter, one string. but you can decide of a "separator", that will define two parts to the message.
e.g. - instruct people to write "XXX" in the message, before "first arg" and "second arg".
check that legal else dut_error("ONE thing", "XXX", "another thing");
check that x < 7 else dut_error("failure ", "XXX", "of x not 7 but is ", x);
extend dut_error_struct {
write() is first {
var message_parts := str_split(get_message(), "XXX");
if message_parts.size() == 2 {
out ("First part of message is ", message_parts[0],
"\nand second part of message is ", message_parts[1]
);
};
};
I could get pretty close to what I want using the dut_errorf method combined with a preprocessor directive defining the format string:
#define DUT_FORMAT "first argument is %s and second argument is %s"
check that FALSE else dut_errorf(DUT_FORMAT, "check1", "check2");
but I would still prefer a way that doesn't require this DUT_FORMAT directive and instead uses dut_error_struct or something similar.

SystemVerilog $test$plusargs matches substring

We usually write testcases with VCS plusargs as follows
if($test$plusargs("Hello"))
do_hello_stimulus();
else if($test$plusargs("Hello1"))
do_hello1_stimulus();
But I found out $test$plusargs match even the substring. Even if we pass Hello1, it will call do_hello_stimulus(). Can anyone help me out how I should use to match exact string?
Thanks in advance
this is exactly the behavior defined in the standard. The $test$plusargs matches the prefix of an arg.
You can use the $value$plusargs instead to check the remainder of the string. Something like this:
if ($value$plusargs("hello%s", rest)) begin
if (rest == "")
$display("hello");
else
$display("hello: %s", rest);
end
else
$display("error");

How can I get the name of procedure in Nim?

I am trying to write a macro for debug print in the Nim language.
Currently this macro adds filename andline to the output by instantiationInfo().
import macros
macro debugPrint(msg: untyped): typed =
result = quote do:
let pos = instantiationInfo()
echo pos.filename, ":", pos.line, ": ", `msg`
proc hello() =
debugPrint "foo bar"
hello()
currently output:
debug_print.nim:9: foo bar
I would like to add the name of the procedure (or iterator) of the place where the macro was called.
desired output:
debug_print.nim:9(proc hello): foo bar
How can I get the name of procedure (or iterator) in Nim, like __func__ in C?
At runtime you can do getFrame().procname, but it only works with stacktrace enabled (not in release builds).
At compile-time surprisingly I can't find a way to do it. There is callsite() in macros module, but it doesn't go far enough. It sounds like something that might fit into the macros.LineInfo object.
A hacky solution would be to also use __func__ and parse that back into the Nim proc name:
template procName: string =
var name: cstring
{.emit: "`name` = __func__;".}
($name).rsplit('_', 1)[0]
building on answer from #def- but making it more robust to handle edge cases of functions containing underscores, and hashes containing trailing _N or not
also using more unique names as otherwise macro would fail if proc defines a variable name
import strutils
proc procNameAux*(name:cstring): string =
let temp=($name).rsplit('_', 2)
#CHECKME: IMPROVE; the magic '4' chosen to be enough for most cases
# EG: bar_baz_9c8JPzPvtM9azO6OB23bjc3Q_3
if temp.len>=3 and temp[2].len < 4:
($name).rsplit('_', 2)[0]
else:
# EG: foo_9c8JPzPvtM9azO6OB23bjc3Q
($name).rsplit('_', 1)[0]
template procName*: string =
var name2: cstring
{.emit: "`name2` = __func__;".}
procNameAux(name2)
proc foo_bar()=
echo procName # prints foo_bar
foo_bar()
NOTE: this still has some issues that trigger in complex edge cases, see https://github.com/nim-lang/Nim/issues/8212

why pyang does not throw error in this scenario

the following when condition is referring to a non existing node. I wonder why pyang does not throw error ? It does, if I use a wrong prefix though.
can you review the when conditions (embedded in the module) please.
is it allowed (in when expression) to refer to schema out of the augment itself ?
module mod-w-1 {
namespace "http://example.org/tests/mod-w-1";
prefix m1;
container m1 {
leaf b1 {
type string;
}
}
}
module when-tests {
namespace "http://example.org/tests/when-tests";
prefix wt;
import mod-w-1 {
prefix m1;
}
augment "/m1:m1" {
// when "/m1:m1/b3 = 'abc'";
// there is no b3, so, should be invalid.
// when "/m1:m1/b1 = 'abc'";
// a payload or data situation that has m1/b1 != 'abc' will cause the
// data that fits this augment content will be invalid/rejected.
/* for ex;
<m1>
<b1>fff</b1>
<x>sfsf</x>
<conditional>
<foo>dddd</foo>
</conditional>
</m1>
is invalid, hence, the <x> and <conditional> parts will be
rejected.
*/
leaf x {
type string;
}
container conditional {
leaf foo {
type string;
}
}
}
}
That is because pyang does not validate semantics of XPath expressions at all, only their syntax - and a couple of additional checks, such as function and prefix usage. You will need another YANG compiler to validate those properly.
def v_xpath(ctx, stmt):
try:
toks = xpath.tokens(stmt.arg)
for (tokname, s) in toks:
if tokname == 'name' or tokname == 'prefix-match':
i = s.find(':')
if i != -1:
prefix = s[:i]
prefix_to_module(stmt.i_module, prefix, stmt.pos,
ctx.errors)
elif tokname == 'literal':
# kind of hack to detect qnames, and mark the prefixes
# as being used in order to avoid warnings.
if s[0] == s[-1] and s[0] in ("'", '"'):
s = s[1:-1]
i = s.find(':')
# make sure there is just one : present
if i != -1 and s[i+1:].find(':') == -1:
prefix = s[:i]
# we don't want to report an error; just mark the
# prefix as being used.
my_errors = []
prefix_to_module(stmt.i_module, prefix, stmt.pos,
my_errors)
for (pos, code, arg) in my_errors:
if code == 'PREFIX_NOT_DEFINED':
err_add(ctx.errors, pos,
'WPREFIX_NOT_DEFINED', arg)
elif ctx.lax_xpath_checks == True:
pass
elif tokname == 'variable':
err_add(ctx.errors, stmt.pos, 'XPATH_VARIABLE', s)
elif tokname == 'function':
if not (s in xpath.core_functions or
s in yang_xpath_functions or
(stmt.i_module.i_version != '1' and
s in yang_1_1_xpath_functions) or
s in extra_xpath_functions):
err_add(ctx.errors, stmt.pos, 'XPATH_FUNCTION', s)
except SyntaxError as e:
err_add(ctx.errors, stmt.pos, 'XPATH_SYNTAX_ERROR', e)
Line 1993 of statements.py.
Note that an XPath expression referring to a non-existent node is technically not invalid, not from XPath specification perspective. It just means that an empty node set will be selected by the location path (and that your condition will be false forever).
Yes, you can refer to nodes that are "above" the augment's target node or are its siblings - in fact, you always should when when statement is in play (it should not refer to any node made conditional by it).
Also, you should never attempt to break "module confinement" with a non-prefixed node test (such as b3 and b1). The XPath expression is only able to see names that are defined in imports of the defining module and the defining module itself. For example, even if b3 is later augmented by some unknown third module, your condition would still evaluate to false. It is best to assume that non-prefixed names belong to the defining module's namespace.