唐山企业建网站,广告设计公司开的版面费,服装技术支持东莞网站建设,网络科技公司注册要求我最近在看Synopsys的MPHY仿真代码#xff0c;想以此为参考写个能实现PWM-G1功能的MPHY#xff0c;并应用于ProFPGA原型验证平台。我从中抽取了一部分代码#xff0c;用Vivado自带的仿真器进行仿真#xff0c;然后就遇到了一个莫名其妙的问题#xff0c;谨以此文作为debug…我最近在看Synopsys的MPHY仿真代码想以此为参考写个能实现PWM-G1功能的MPHY并应用于ProFPGA原型验证平台。我从中抽取了一部分代码用Vivado自带的仿真器进行仿真然后就遇到了一个莫名其妙的问题谨以此文作为debug记录。
一、原始问题
涉及到的相关代码如下
第一张图是我从MPHY仿真代码里copy的一个task用于对MPHY进行参数配置第二张图是我要配置的MPHY参数第三张图是选取的一个出问题的参数模块例化第四张图是这个参数模块的实现非常简单。 就是这么简单的几行代码却意外出问题了仿真波形如下图所示可以看到参数没有配置成功。
我真的是百思不得其解就用了一个下午进行debug。 二、问题简化
由于原始问题的仿真工程比较大仿真时间比较长debug起来就很费劲。于是我就把问题的关键部分抽取出来做了简化写了如下的一段仿真代码
// *****************************************************************************
// * *
// * Vivado simulation. *
// * *
// * Author: ZhengWei *
// * Date : 2024/02/06 *
// *****************************************************************************timescale 1ns / 1ps module tb; // Clock ans reset ports of the modulereg sys_clk ;reg sys_rst ;// Tx config interface portsreg [7:0] tx_attrid ;reg [7:0] tx_attrwrval ;reg tx_attrwrn ;reg tx_configenable ;wire write_en ;wire cfg_sel ;reg [7:0] dataout ; //------------------------------------------------------------------------------------parameter SYSCLK_FREQ 38.4 ; initial sys_clk 1b0;initial foreverbegin#(1000.0/(2*SYSCLK_FREQ));sys_clk ~sys_clk;endtask automatic write_shadow_cfg(input [7:0] attrid, input [7:0] attrwrval);begin tx_attrid 8h00;tx_attrwrval 8h00; (posedge sys_clk) begin tx_configenable 1b0 ;tx_attrwrn 1b0 ;tx_attrid attrid ;tx_attrwrval attrwrval;end (posedge sys_clk) begin tx_configenable 1b1 ;tx_attrwrn 1b1 ;tx_attrid attrid ;tx_attrwrval attrwrval;end(posedge sys_clk) begintx_configenable 1b0 ;tx_attrwrn 1b0 ;tx_attrid 8h00;tx_attrwrval 8h00; endendendtaskinitial begintx_configenable 1b0 ;tx_attrwrn 1b0 ;tx_attrid 8h00;tx_attrwrval 8h00;sys_rst 1b1 ;#100sys_rst 1b0 ;#200; write_shadow_cfg(8h2d, 8h20);#200;write_shadow_cfg(8h2d, 8h25);write_shadow_cfg(8h2d, 8h30);# 500 ;$stop ;endassign write_en tx_configenable tx_attrwrn;assign cfg_sel (tx_attrid 8h2d);always (posedge sys_clk or posedge sys_rst) beginif (sys_rst)dataout 8h00;else if(write_en cfg_sel) dataout tx_attrwrval;else dataout dataout;endendmodule
三、问题定位
按如上代码进行仿真复现了问题波形如下图所示 先写了个20结果是20正确再写了个25但结果是0错误最后写了个30结果是30正确。
其实我一开始只写了个20发现结果是正确的。我还想了很久为啥原始仿真工程是错误的呢
后面就连着写了25和30才发现先写的25结果是错的后写的30结果是对的。
特别注意写20后面加了delay但25和30中间没有加delay。
四、问题解决
虽然这结果也很让人费解但不加delay就有问题不由得让我怀疑下面这两句有问题 把这两句注释掉重新仿真结果正确波形图如下 五、进一步分析
按我的理解这两句也就只是在task开始时给信号赋个初始值而已为啥就会导致结果变成0了呢还是不能理解为了理解这个结果0是怎么来的让问题能变得再清晰点改成如下 重新仿真后的波形图如下所示 我们能在波形里看到ff但却是更加莫名其妙了。隐隐感觉这可能与阻塞赋值和非阻塞赋值有关虽然还是不能理解但改成如下进行仿真 重新仿真后的波形图如下所示可以看到结果是正确的 六、总结与疑问
以前读书时只记住了“组合逻辑用阻塞赋值时序逻辑用非阻塞赋值”然后就是教科书里的几个加delay的例子感觉还都能理解。
也看了下面这个例子感觉和我当前的这个例子还是有区别的。
modelsim和vivado仿真不一致——噩梦debug - 代码先锋网
再看了下面这个链接感觉还是没有特别理解为啥我这个例子里用阻塞赋值会是这样的结果。
verilog中阻塞和非阻塞的区别_verilog阻塞和非阻塞的区别-CSDN博客
时间和精力有限这个问题先暂时这样了如果有大佬路过可以赐教下不胜感激