modelsim之inout类型tb文件编写及仿真

很久没更新了,这边文章是笔者在隔离期间写的,之前接触过inout类型的仿真,但很久未使用有些生疏了,查阅了相关资料编写了这篇文章,一来是当作笔记,忘记时随时查阅,二来是为了供广大FPGA爱好者学习参考,如有纰漏,请批评指正。

我们都知道,在电路中有输入端口(input)、输出端口(output)、双向口(inout)。像诸如I2C协议的器件都是采用两根线进行主从通讯,一个是时钟线sck,另一个是数据线sda。在主机与从机需要通讯时,主机就会往从机发生sck信号,若主机需要往从机发生数据,sda信号则从主机流向从机(如1流向),反之,主机需要得到从机的数据,sda信号则从从机流向主机(如2流向),I2C协议还有很多知识点,本文只对双向口仿真进行阐述。此时可以发现sda信号在读写两个状态时流向不同,那这种信号该如何仿真呢?

modelsim之inout类型tb文件编写及仿真

在写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,…);即可实现功能。

modelsim之inout类型tb文件编写及仿真

上图为我镶嵌的iicwp的测试代码,其中iic_m_write也是有task语句编写的函数,该功能会向iic中发送8’h04,8’h00,8’h00,8’h01,8’h01。

仿真截图如下:

modelsim之inout类型tb文件编写及仿真

今天的分享就到这里,如有错误,请指正,谢谢。
欢迎关注我的个人公众号,有问题可留言。
modelsim之inout类型tb文件编写及仿真

上一篇:【Redis】Nosql非关系型数据库


下一篇:ODBC连接达梦数据库配置