标签:仿真 task 主机 modelsim 从机 sda tb reg inout
很久没更新了,这边文章是笔者在隔离期间写的,之前接触过inout类型的仿真,但很久未使用有些生疏了,查阅了相关资料编写了这篇文章,一来是当作笔记,忘记时随时查阅,二来是为了供广大FPGA爱好者学习参考,如有纰漏,请批评指正。
我们都知道,在电路中有输入端口(input)、输出端口(output)、双向口(inout)。像诸如I2C协议的器件都是采用两根线进行主从通讯,一个是时钟线sck,另一个是数据线sda。在主机与从机需要通讯时,主机就会往从机发生sck信号,若主机需要往从机发生数据,sda信号则从主机流向从机(如1流向),反之,主机需要得到从机的数据,sda信号则从从机流向主机(如2流向),I2C协议还有很多知识点,本文只对双向口仿真进行阐述。此时可以发现sda信号在读写两个状态时流向不同,那这种信号该如何仿真呢?
在写Verilog程序时,我们都知道reg类型只能在initial、always等里面赋值,而wire类型可以在assign里面赋值。作为双向口的sda信号我们既希望它作为输入,也希望它作为输出,因此wire类型最为合适。
对于双向口的仿真,我通常会在tb文件中这样定义:
reg sck;
wire sda;
reg sda_r;
reg sda_en;
assign sda_r = (sda_en) ? mosi : 1'bz;
assign sda =sda_r;
当sda作为输入时,sda_en应为0,此时sda为高阻态,sda会相应外界连接的信号高低电平。当作为输出时,sda_en应为1,此时mosi作为要输出的sda的数据,根据时序对应写出仿真文件即可。
由于i2c的时序都是固定的,为了方便仿真文件的编写,我会采用task语句将时序打包,方便自己对程序的理解。
task task_name;
input inputname1;
input inputname2;
..
reg regname1;
reg regname2;
..
begin
... //具体程序执行的内容
...
end
endtask
在initial里面使用task_name(inputname1,inputname2,…);即可实现功能。
上图为我镶嵌的iicwp的测试代码,其中iic_m_write也是有task语句编写的函数,该功能会向iic中发送8’h04,8’h00,8’h00,8’h01,8’h01。
仿真截图如下:
今天的分享就到这里,如有错误,请指正,谢谢。
欢迎关注我的个人公众号,有问题可留言。
标签:仿真,task,主机,modelsim,从机,sda,tb,reg,inout 来源: https://blog.csdn.net/weixin_45372778/article/details/121929711
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。