带参数的宏定义的一种用法

1 丶应用场景:

当我们 interface 中有几组信号的驱动或采样方式相同时,我们可以把 interface 中的信号作为参数来声明宏定义,将这些相同的操作以带参数的宏定义方式抽象出来。

2 丶举例:

前段时间写 axi master bfm 时,axi 有 5 个通道,每个通道都有一个握手机制;
当 a 信号拉高后,进入等待握手状态,开启一个无限循环进程,开始每拍进行计数,并判断是否超时;
当 b 信号拉高后,计数器清零,跳出循环进程,并将 a 信号拉低复位。
同时设置一个开关 c,来控制是否开启超时检查。

`define wait_handshake(a, b, c) \
    forever begin \
        @(posedge clk); \
        cnt++; \      
        if(``a``=== 1'b1 && ``b`` === 1'b1) begin \
            cnt = 0; \
            break; \
        end else if(cnt > cfg.cnt && ``c``) begin \
            $display("out time."); \
        end \
    end \
    ``b`` <= 1'b0; \

3 丶缺陷:

由于宏定义的特性,我们定义的带参数的宏定义表示的是一行代码;
如果我们定义的带参数的宏定义过长,出现了错误,编译器无法给出精准的出错位置,只能指出是哪行的宏定义有问题,而无法指到宏定义内部,这无疑是给 DEBUG 增加了难度。

4 丶其他:

那我们为什么没有将它抽象成 task?
因为声明 task 要指明参数的类型及位宽,而宏定义的参数则不需要;
往往我们 interface 中几组信号的驱动或采样方式相同时,但他们的位宽并不相同。
还有一个好处,task 的作用域只局限于当前 object,而宏定义则是全局;
但这也有个坏处,如果我们不熟悉环境,可能找不到宏定义是在哪声明的,使代码的可读性变弱了。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇