全加器分层测试平台输出错误,请求代码修正方案
全加器分层测试平台错误修正方案
问题描述
实践全加器分层测试平台方法学时,搭建了包含Design、Interface、Transaction Class等模块的完整测试环境,但仿真输出中Monitor和Scoreboard的结果错误,具体仿真输出如下:
------------------------------ Generator ------------------------------ a = 0, b = 1, c = 1 sum = 0, carry = 0 ------------------------------ ------------------------------ Driver ------------------------------ a = 0, b = 1, c = 1 sum = 0, carry = 0 ------------------------------ ------------------------------ Monitor ------------------------------ a = 0, b = 1, c = 1 sum = 0, carry = 0 ------------------------------ Result is as Expected ------------------------------ Scoreboard ------------------------------ a = 0, b = 1, c = 1 sum = 0, carry = 0 ------------------------------ $finish at simulation time 3000 V C S S i m u l a t i o n R e p o r t Time: 3000 ps
错误根源分析与修改方案
1. 半加器模块逻辑错误(核心问题)
原half_adder模块中,与门的输出错误连接到了和信号s,导致半加器进位输出完全错误,进而引发全加器结果异常。
修改前代码:
module half_adder(a,b,s,c); input a,b; output s,c; xor x1(s,a,b); and a1(s,a,b); // 错误:将进位输出连接到和信号s endmodule
修改后代码:
module half_adder(a,b,s,c); input a,b; output s,c; xor x1(s,a,b); and a1(c,a,b); // 修正:将与门输出连接到进位c endmodule
2. Driver模块时序错误
Driver在给接口赋值后立刻读取DUT输出,此时组合逻辑尚未稳定,读取到的是未更新的旧值。需添加延迟等待信号稳定。
修改前代码:
task main; repeat(1) begin transaction trans; gen2driv.get(trans); vif.a <= trans.a; vif.b <=trans.b; vif.c <=trans.c; trans.s_out = vif.s_out; // 赋值后立刻读取,信号未稳定 trans.c_out = vif.c_out; trans.display("Driver"); end endtask
修改后代码:
task main; repeat(1) begin transaction trans; gen2driv.get(trans); vif.a <= trans.a; vif.b <=trans.b; vif.c <=trans.c; #1; // 添加延迟等待组合逻辑稳定 trans.s_out = vif.s_out; trans.c_out = vif.c_out; trans.display("Driver"); end endtask
3. Scoreboard模块逻辑表达式优先级错误
进位判断表达式中,==优先级高于位或|,导致逻辑判断逻辑混乱,需将整个进位计算表达式用括号包裹后再与trans.c_out比较。
修改前代码:
if(((trans.a ^ trans.b ^ trans.c) == trans.s_out) && ((trans.a & trans.b) |(trans.b & trans.c) |(trans.c & trans.a) == trans.c_out))
修改后代码:
if(((trans.a ^ trans.b ^ trans.c) == trans.s_out) && (((trans.a & trans.b) | (trans.b & trans.c) | (trans.c & trans.a)) == trans.c_out))
4. Monitor模块时序优化
保留现有#3延迟,确保在Driver完成赋值且DUT输出稳定后再采样,避免读取到未稳定的信号:
task main; repeat (1) begin #3; // 等待Driver赋值后DUT输出稳定 transaction trans; trans = new(); trans.a = vif.a; trans.b = vif.b; trans.c = vif.c; trans.s_out = vif.s_out; trans.c_out = vif.c_out; mon2scb.put(trans); trans.display("Monitor"); end endtask
修正后预期结果
对于输入a=0, b=1, c=1,全加器正确结果应为sum=0, carry=1,修正后Monitor和Scoreboard将输出该正确值,Scoreboard的判断逻辑也会正常验证结果。
内容的提问来源于stack exchange,提问作者Srijoy
相关产品推荐
相关产品推荐

