systemverilog如何实现可变参数宏
假设我想实现如下的功能.
`define DIS(str) $display(str)
然后,`DIS("hello,world,%d",'h8);
编译会报错。我想把 "hello,world,%d",'h8 当做统一的参数传进去,单是编译器会检测到“,”认为是两个参数。
大家不要说DIS的宏给两个参数,因为我可能需要打印这样的信息,"hello,world,%d,%d",'h8,'h19
其实我想实现的是类似于C语言中可变参数宏的功能,求大牛指导。
你只给了display一个参数, dispay会把参数当成一个字符串打印出来,`DIS("hello,world,%d",'h8) 这样会把括号里的当成一个字符串来处理。最后打印出来的就是"hello,world,%d",'h8。
再则`DIS("hello,world,%d",'h8)这么写是给了两个参数的。应写成`DIS(“\"hello,world,%%d\",'h8”) 是给一个字符串参数。
应该转义
2# 的方法好像不可以 编译都有问题
是不是根本实现不了?
systemverilog lrm 3.1a 关于define就下面几行说明:
25.2 ‘define macros
In Verilog, the ‘definemacro text can include a backslash ( \) at the end of a line to show continuation on
the next line.
In SystemVerilog, the macro text can also include `", `\`"and ``.
An `"overrides the usual lexical meaning of", and indicates that the expansion should include an actual quotation mark. This allows string literals to be constructed from macro arguments.
A `\`"indicates that the expansion should include the escape sequence \", e.g.
`define msg(x,y) `"x: `\`"y`\`"`"
This expands:
$display(`msg(left side,right side));
to:
$display("left side: \"right side\"");
A ``delimits lexical tokens without introducing white space, allowing identifiers to be constructed from arguments, e.g.
`define foo(f) f``_suffix
This expands:
‘foo(bar)
to:
bar_suffix
Accellera
SystemVerilog 3.1a Extensions to Verilog-2001
344 Copyright 2004 Accellera. All rights reserved .
The ‘includedirective can be followed by a macro, instead of a literal string:
‘define home(filename) ‘"/home/foo/filename‘"
‘include ‘home(myfile)
我只用vcs,以下结论是在vcs下得出的,有条件的同学可以用其他编译器试试。
sv的手册中很多例子是有问题的,不能只看手册中写的, 要动手测测。这个问题有可能是编译器的问题。
你说的`define msg(x,y) `"x: `\`"y`\`"`"这个写法没有问题,但是不加重音号(`)也是没问题的,这个不知道你在vcs下测过吗。
其实有一种情况是必须加重音号的,就是宏的引用在双引号内部。下面有个例子。还有小编要注意的一点是define的字符串替换时在编译阶段,不是在仿真阶段,一定要保证编译阶段字符串替换的正确性。
楼上的同学,你觉得我想打印的效果是,
"hello,world,%d",'h8
吗?
查了很多资料,试了很多方法,都木有实现。
估计sv根本就没办法实现这样的功能吧。
define DIS $display 就可以实现一楼的操作 你想宏参数是个数组 后面替换部分就要实现数组引用
既然是宏处理的话,自己用perl写个宏预处理程序。在编译前先处理一下,不必强求用SV实现。
小编是要实现这样的功能吗?
`define DIS "hello,world,%d,%h",'h8,5'd15
$display(`DIS);
//打印信息
# hello,world,8,0f
sv很强大的,不是不能实现,而是你不会而已
哥,我要这样的功能有啥用。
好好看看1楼好吗?
你要的功能:我想把 "hello,world,%d",'h8 当做统一的参数传进去,单是编译器会检测到“,”认为是两个参数。
大家不要说DIS的宏给两个参数,因为我可能需要打印这样的信息,"hello,world,%d,%d",'h8,'h19
我的方式:
`define DIS1 "hello,world,%d",'h8
`define DIS2 "hello,world,%d,%h",'h8,5'd15
`define DIS3 "hello,world,%d,%h,%d",'h8,5'd15,6'h11
`define DIS11 "hello,world,%d"
`define DIS22 "hello,world,%d,%h"
`define DIS33 "hello,world,%d,%h,%d"
$display(`DIS1);
$display(`DIS2);
$display(`DIS3);
$display(`DIS11,data1);
$display(`DIS22,data1,data2);
$display(`DIS33,data1,data2,data3);
还有,请好好看看我上一次的回答:我问小编你是要实现这个功能吗?你就这么不客气的答复?好心帮你花时间回答,我找罪受...
如果是你1楼写的方式 ,就是DIS换成$display有意义? 一定要实现你1楼的写法那么7楼给你的回答就是最好的,好好想想你要实现什么功能。
7# 的回答:define DIS $display 就可以实现一楼的操作
小编说了要实行的是类似C里面可变参数宏,像下面这样的
#defien err(...)fprintf(stderr, __AV_ARGS__)
宏调用 err("%s file total %dMB.\n", "hello.c", 2) ;
预处理后为: fprintf(stderr, %s file total %dMB.\n", "hello.c",2) ;
SV就是没法定义可变参数的宏。
你这一堆 DIS** 有什么意义么?没有任何灵活性
谢谢你帮我回答。
`define DIS(str) $display(str)
然后,`DIS("hello,world,%d",'h8);
`DIS("hello,world,%d",'h8);比$display("hello,world,%d",'h8);优点在哪里?7#的回答不能实现这个功能?