动态设计参考网站,哈尔滨企业自助建站,网站建二级目录,seo基础教程视频Verilog自适应位宽与固定位宽的不兼容问题
问题起源
我在写verilog代码的时候#xff0c;有两个模块shifter和round#xff0c;参数化的shifter模块已经通过了测试#xff0c;round模块是shifter的上层模块#xff0c;对round模块进行16位测试的时候#xff0c;顺利通过…Verilog自适应位宽与固定位宽的不兼容问题
问题起源
我在写verilog代码的时候有两个模块shifter和round参数化的shifter模块已经通过了测试round模块是shifter的上层模块对round模块进行16位测试的时候顺利通过测试但是在进行24位测试的时候发现仿真总是报一大堆红色的叉
排错流程
首先怀疑round写错了但是反复查阅文献和公式发现并没有错误因此进一步怀疑是shifter出错了再一次测试shifter的24位执行情况发现shifter参数化执行得非常好无论是多少位的测试都能正确执行于是明确了
shifter模块完全正确通过测试错误只有可能是round里面发生的。
因而再次检视round的代码其中x_out的结果由三个通过shifter计算得到的变量共同计算得出于是将这三个变量的值也设置为round的输出展示出来也就是图中的a,b,c以便检错仿真运行得到的结果如图 可见三个通过shifter计算得到的变量也是红色的叉这表明shifter模块并未能正确计算出这些值前面已经得到结论 shifter模块完全正确通过测试错误只有可能是round里面发生的。 但是现有条件可以推断出shifter模块并未能正确计算出这些值
综上错误范围可以进一步缩小应该在round调用shifter的过程中出现了问题
检错步骤
重新检视round的代码发现对shifter的调用中似乎出现了问题 再确认shifter中对参数的描述 这里面显然shifter模块的shifter_amount变量属于自适应位宽的值然而round在调用的过程中指定了182的位宽为4位当参数n24时传入shifter会自适应地计算shifter_amount的位宽也就是24取对数那么位宽就是5这与调用shifter时传入的参数4d8指明位宽为4不同因而导致了shifter模块执行出错。 至此得到了问题的关键 round模块在调用shifter时提供了指定位宽的变量然而shifter在获取该变量时设定了自适应位宽从而导致了shifter模块失效最终造成了round模块输出结果全是红叉的问题。
问题解决
在round模块中将指定的位宽值去掉 //decryption shifter #(n) S1 (y_in, 1b0, 1, S1_sig_1);shifter #(n) S2 (y_in, 1b0, 8, S8_sig_1);shifter #(n) S3 (y_in, 1b0, 2, S2_sig_1);//encryptionshifter #(n) S11 (x_in, 1b0, 1, S1_sig_0);shifter #(n) S22 (x_in, 1b0, 8, S8_sig_0);shifter #(n) S33 (x_in, 1b0, 2, S2_sig_0);再次执行仿真结果如下图可以见得红叉没有了 使用c语言编写执行相同操作的代码
void RoundCaculate(mpz_t x_in, mpz_t y_in, mpz_t key, mpz_t x_out, mpz_t y_out, int width, bool mode) {mpz_t s1, s2, s8;mpz_init(s1);mpz_init(s2);mpz_init(s8);if (mode)//mode1进行加密mode0进行解密{//加密操作shifter(s1, x_in, 1, 0, width);shifter(s2, x_in, 2, 0, width);shifter(s8, x_in, 8, 0, width);mpz_and(x_out, s1, s8);mpz_xor(x_out, x_out, y_in);mpz_xor(x_out, x_out, s2);mpz_xor(x_out, x_out, key);mpz_set(y_out, x_in);}else {//解密操作shifter(s1, y_in, 1, 0, width);shifter(s2, y_in, 2, 0, width);shifter(s8, y_in, 8, 0, width);mpz_and(y_out, s1, s8);mpz_xor(y_out, y_out, x_in);mpz_xor(y_out, y_out, s2);mpz_xor(y_out, y_out, key);mpz_set(x_out, y_in);}//gmp_printf(\n%Zx\n%Zx\n%Zx\n,s1,s2,s8);mpz_clear(s1);mpz_clear(s2);mpz_clear(s8);
}使用相同的样例进行测试 可以看到两次测试结果一致问题顺利解决。
反思
既然都下决心要参数化那就尽量少指定位宽。