Verilog自定义函数返回逻辑错误值,求排查原因
Verilog函数返回值与预期不符的问题排查
问题根源分析
你的问题出在未指定位宽的常量导致数值截断,再加上函数返回值的位序设计,最终引发了输出偏差:
- Verilog中未声明位宽的整数常量(如
1)默认是32位。当你执行a0 ^ 1时,1bit的a0会被零扩展到32位,异或结果为32位值(a0=0时为32'h00000001)。 - 该32位值与1bit的
r(同样被扩展到32位)做&操作后,结果仍是32位。 - 拼接
{(a0^1)&r, (a1^1)&r}会生成64位向量,但你的函数返回值仅为[0:1](两位),赋值时会截断64位值的高位,只保留最低两位:- 64位拼接结果的bit0是1(来自第二个操作数的最低位),bit1是0(来自第一个操作数的bit1,而第一个操作数是
32'h00000001,bit1为0)。 - 函数返回值的位序是
[0:1](索引0为高位,1为低位),因此test[0] = 0,test[1] = 1,对应数值为2'b01。
- 64位拼接结果的bit0是1(来自第二个操作数的最低位),bit1是0(来自第一个操作数的bit1,而第一个操作数是
- 赋值给
out[1:0](索引1为高位,0为低位)时,数值2'b01对应out[1]=0、out[0]=1,与你观察到的结果完全一致。
解决方案
以下两种修复方式任选其一即可:
方法1:使用明确的1bit常量
将所有整数常量替换为1bit的Verilog常量(1'b1),确保所有操作都在1bit位宽下进行,避免不必要的位扩展和截断:
function [0:1] test ( input a0, input a1, input r ); begin test = {(a0 ^ 1'b1) & r, (a1 ^ 1'b1) & r}; end endfunction
方法2:调整函数返回值的位序为大端模式
将函数返回值的位序改为[1:0](与out[1:0]的位序一致),同时配合明确的1bit常量,让拼接顺序直接对应目标位序:
function [1:0] test ( input a0, input a1, input r ); begin test = {(a0 ^ 1'b1) & r, (a1 ^ 1'b1) & r}; end endfunction
此时拼接的第一个表达式会赋值给test[1](高位),第二个赋值给test[0](低位),与out[1:0]的位序完全匹配,赋值后out[1]和out[0]都会是1。
测试平台修正
你的测试平台中存在位宽不匹配的问题:out是64位向量,判断out == 63'h0会引发错误,建议修改测试条件为:
if(!(out == 64'h0000000000000003)) begin // out[1:0]为11,其余位为0 $display("Test 0 failed"); $stop; end
内容的提问来源于stack exchange,提问作者xsimplex
相关产品推荐
相关产品推荐

