我正在使用与 UVM 不兼容的旧环境,但使用 vr_ad_reg。这个旧环境的一个问题是,不是为其中一个模块实例化 regfile 两次(在 RTL 中确实实例化了两次),而是对整个 regfile 和其中的寄存器进行双重定义。
例如,我有两个 regfile:“GAD”和“GAD_RX”,它们都有一个这样定义的寄存器:
reg_def GAD_SEQ GAD 20'h00010 {
reg_fld s_event : uint (bits : 7) : RW : 0x0;
reg_fld smpl_en : bit : RW : 0x0;
reg_fld int_en : bit : RW : 0x0;
reg_fld dma_req : bit : RW : 0x0;
reg_fld smpl_tag : uint (bits : 2) : RW : 0x0;
reg_fld ch_tag : uint (bits : 4) : RW : 0x0;
reg_fld smpl_point : uint (bits : 16) : RW : 0x0;
};
reg_def GAD_RX_SEQ GAD_RX 20'h00010 {
reg_fld s_event : uint (bits : 7) : RW : 0x0;
reg_fld smpl_en : bit : RW : 0x0;
reg_fld int_en : bit : RW : 0x0;
reg_fld dma_req : bit : RW : 0x0;
reg_fld smpl_tag : uint (bits : 2) : RW : 0x0;
reg_fld ch_tag : uint (bits : 4) : RW : 0x0;
reg_fld smpl_point : uint (bits : 16) : RW : 0x0;
};
如您所见,regs 是相同的。我不希望替换整个定义,因为它基于也生成 RTL 的脚本,并且尝试重写它们太麻烦和风险。但是,我确实希望能够通过将它们约束到任一 GAD 来编写一个可以写入它们的序列。
我为写入这些寄存器的所有序列定义了一个结构成员:
type gad_type_t : [GAD,RX_GAD];
extend ocp_master_sequence_kind_t : [CONFIG_ADC_SEQ];
//This sequence writes a single line to GAD sequencer
extend CONFIG_ADC_SEQ ocp_master_sequence_q {
smpl_point : int(bits:16);
dma_req : bit;
int_en : bit;
smpl_en : bit;
ch_tag : uint(bits:4);
smpl_tag : uint(bits:2);
samp_sig : uint(bits:4);
keep soft samp_sig==0;
//which GAD to config
gad_type : gad_type_t;
keep soft gad_type==GAD;
我尝试用宏声明寄存器变量但完全失败:
//Macro for declaring either GAD or RX_GAD register variable
define <get_gad_reg'action> "gad_reg <var_name'name> : <gad_type'exp> <reg_suffix'exp>" as computed {
var gad_regname : string;
var gad_type : gad_type_t = <gad_type'exp>;
var reg_suffix_s : string = <reg_suffix'exp>;
gad_regname = gad_type == RX_GAD ? append("GAD_RX_",reg_suffix_s) : append("GAD_",reg_suffix_s);
return append("var ",<var_name'name>," : ",gad_regname," vr_ad_reg = driver.get_reg_by_kind(",gad_regname,").as_a(",gad_regname," vr_ad_reg)");
};
宏应该在序列主体内以这种方式使用:
gad_reg gad_seq_r : gad_type SEQ;
我希望能翻译成:
var gad_seq_r : GAD_SEQ vr_ad_reg = driver.get_reg_by_kind(GAD_SEQ).as_a(GAD_SEQ vr_ad_reg);
或者:
var gad_seq_r : GAD_RX_SEQ vr_ad_reg = driver.get_reg_by_kind(GAD_RX_SEQ).as_a(GAD_RX_SEQ vr_ad_reg);
它适用于 GAD,但不适用于 RX_GAD,经过多次调试,我推断出 gad_type 没有正确匹配,并且宏只是在条件赋值中使用 else 子句。
我决定尝试一种不同的方法而不使用宏,我尝试在序列本身中使用“when”子句:
when GAD {
body()@driver.clock is {
var gad_seq_r : GAD_SEQ vr_ad_reg = driver.get_reg_by_kind(GAD_SEQ).as_a(GAD_SEQ vr_ad_reg);
};
};
when RX_GAD {
body()@driver.clock is {
var gad_seq_r : GAD_RX_SEQ vr_ad_reg = driver.get_reg_by_kind(GAD_RX_SEQ).as_a(GAD_RX_SEQ vr_ad_reg);
};
};
body()@driver.clock is also {
gad_seq_r.smpl_point = last_line ? 0x8000 : smpl_point;
gad_seq_r.ch_tag = ch_tag;
gad_seq_r.smpl_tag = smpl_tag;
gad_seq_r.dma_req = dma_req;
gad_seq_r.int_en = int_en;
gad_seq_r.smpl_en = smpl_en;
gad_seq_r.s_event = s_event[6:0];
do WR_REG seq keeping {.reg==gad_seq_r;};
};
这不会编译,因为编译器无法识别 'when' 子句之外的 gad_seq_r 。
我不知道在为 GAD 和 RX_GAD 复制代码之外是否有解决方案,但我想我可以在这里试一试。无论哪种方式,下一个项目我们将构建一个更可重用的寄存器数据库。
如果你能活到现在,谢谢你的关注。