《基于FPGA的模拟 IC协议设计.docx》由会员分享,可在线阅读,更多相关《基于FPGA的模拟 IC协议设计.docx(15页珍藏版)》请在第一文库网上搜索。
1、基于FPGA的模拟FC协议设计今天给大侠带来基于FPGA的模拟I2C协议设计,由于篇幅较长,分三篇。今天带来第三篇,下篇,程序的仿真与测试。话不多说,上货。导读I2C(Inter-IntegratedCircuit),其实是I2CBus简称,中文就是集成电路总它是一种串行通信总线,使用多主从架构,由飞利浦公司在1荷库代为了让主板、嵌式系统或壬机用以连接低速周边设备而发展。C的正确读法为“I平方C”(SqUared-C),而“I二C(ITwoY)则是另W种错误但被广泛使用的读法。自2006年10月1日起,使用Fc协议己经不需要支付专利费,但制造商仍然需要付费以获取C从属设备地址。I2C简单来说,
2、就是一种串行通信协议,-C的通信协议和通信接且在很多工程中有广泛的应用,如数据采集领域的串行AD,图像处理领域的摄像头配置,工业控制领域的X射线管配置等等。除此之外,由于Fc协议占用的IO资源特别少,连接方便,所以工程中也常选用Pc接且做为不同芯片间的通信协议。Pc串行总线一般有两根信号线,一根是双向的数据线2A,另一根是时钟线SC1。所有接到Pc总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SC1接到总线的SC1上。在现代电壬系统中,有为数众多的IC需要进行相互之间以及与外界的通信。为了简化电路的设计,Phi1ips公司开发了一种用于内部IC控制的简单的双向两线串行总线I2C
3、(Inte!-IntegratedCircuitbus)。1998年当推出Pc总线协议2.0版本时,Fc协议实际上已经成为一个国际标准。在进行FPGA设计时,经常需要和外围提供I2C接口的甚左通信。例如低功耗的CMOS实时时钟/日历芯片PCF8563、1CD驱动芯片PCF8562、并行扩展芯片PCF8574、键盘/国驱动器Z1G7290等都提供Jc接口。因此在FPGA中模拟Fc接口已成为FPGA开发必要的步骤。本篇将详细讲解在FPGA芯片中使用VHD1/Veri1ogHD1模拟Fc协议,以及编写TeStBenCh仿真和测试程序的方法。第三篇内容摘要:本篇会介绍程序的仿真与测试,包括主节点的仿真
4、、从节点的仿真、仿真主程序、仿真结果以及总结等相关内容。四、程序的仿真与测试I2C协议的模拟程序完成后,还需要通过仿真程序对程序的功能进行测试。对本程序的仿真包括3个部分:第一部分是主节点的仿真,模拟数据读/写;第二部分是从节点的仿真,模拟数据的接收和应答;第三部分是仿真主程序,负责整个仿真过程的控制。4.1 主节点的仿真主节点仿真的内容包括读数据、写数据和比较数据3部分,代码如下:inc1ude”巨mesca1e.v模块定义modu1ewb_master_mode1(e1k,rst,adr,din,dout,eye,stb,we,sei,ack,err,rty);参数parameterdwi
5、dth=32;parameterawidth=32;输入、输出inpute1k,rst;outputawidth-1:0adr;inputdwidth-1:0din;outputdwidth-1:0dout;outputeye,stb;outputwe;outputdwidth/8-1:0sei;inputack,err,rty;/WIRE定义regawidth-1:0adr;regdwidth-1:0dout;regeye,stb;regwe;regdwidth/8-1:0sei;regdwidth-1:01q;/存储逻辑初始化initia1beginadr二awidthbx;dout=dw
6、idth1,bx;eye二b;stb=1bx;we=hx;sei二dwidth/81,bx;#1;end写数据周期taskwbwrite;inputde1ay;integerde1ay;inputawidth-1:0a;inputdwidth-1:0d;begin/延迟repeat(de1ay)(posedgee1k);/设置信号值#1;adr=a;dout=d;eye=1,b1;stb=1b1;we=1b1;sei=dwidth/8b1;(posedgee1k);/等待从节点的应答信号whi1e(ack)(posedgee1k);#1;eye=b;stb=bx;adr=awidthbx;do
7、ut=dwidthbx;we=1hx;sei=dwidth/8bx;endendtask/读数据周期taskwb_read;inputde1ay;integerde1ay;inputawidth-1:0a;outputdwidth-1:0d;begin/延迟repeat(de1ay)(posedgee1k);/设置信号值#1;adr=a;dout二dwidthbx;eye=1,b1;stb=1,b1;we=b;sei=dwidth/8b1;(posedgee1k);/等待从节点应答信号Whi1eCack)(posedgee1k);#1;eye=b;stb=bx;adr=awidthbx;dou
8、t=dwidthbx;we=hx;sei=dwidth/81,bx;d=din;endendtask/比较数据taskwb_cmp;inputde1ay;integerde1ay;inputawidth-1:0a;wb_read(de1ay,a,q);q)inputdwidth-1:0d_exp;if(d_exp!=Sdisp1ayCzDatacompareerror.%h,expected%hatendtaskendmodu1etime%t,q,d_exp,$time);beginReceivedend4.2 从节点的仿真从节点仿真程序需要模拟从主节点接收数据,并发出应答信号,代码如下:in
9、c1udetimesca1e.V模块定义modu1ei2cSIaVemode1(sc1,sda);/参数地址parameterI2C_ADR=Tb001_0000;/输入、输出inputsc1;inoutsda;/变量申明wiredebug二1b1;reg7:0mem3:0;/初始化内存reg7:0mem_adr;/内存地址reg7:0mem_do;/内存数据输出regsta,d_sta;regsto,d_sto;reg7:0sr;/8位移位寄存器regrw;/读写方向wiremy_adr;/地址wirei2c_reset;/RESET信号reg2:0bit_cnt;wireacc_done;
10、/传输完成regId;regsda_o;wiresda_d1y;/状态机的状态定义parameterid1e=3,b000;parameters1ave_ack=3,b001;parameterget_mem_adr=3,b010;parametergma_ack-3,b11;parameterdata=3,b1OO;parameterdata_ack-3,b11;reg2:0state;/模块主体初始化initia1beginsdao=b1;state=id1e;end/产生移位寄存器a1ways(posedgesc1)sr=#1sr6:01sda;检测到访问地址与从节点一致assignmy
11、_adr=(sr7:1=I2C_ADR);产生位寄存器a1ways(posedgesc1)if(Id)bitent=#13,b111;e1sebit_cnt=#1bit_cnt-3h1;产生访问结束标志assignacc_done=!(bit_cnt);/sda延迟assign#1sda_d1y=sda;检测到开始状态a1ways(negedgesda)if(sc1)beginsta=#11,b1;if(debug)Sdisp1ay(zzDEBUGi2c_s1ave;startconditiondetectedat%t,$time);ende1sesta=#1b;a1ways(posedges
12、c1)d_sta=#1sta;/检测到停止状态信号a1ways(posedgesda)if(sc1)beginsto=#11,b1;if(debug)$disp1ay(DEBUGi2c_s1ave;stopconditiondetectedsto=#11,b;i2c_reset=staposedgesto)产生I2C/状态机if(stoII(sta&!dstate=#1id1e;/reset状态机ende1se的RESET信号assigna1ways(negedgesc1orsta)beginsda_o=#1b1;Id=#1b1;/初始化case(state)ende1sesda_o=#11,
13、b1;Idid1e:/id1e状态begin=#11,b;if(acc_done&my_adr)state=#1s1ave_ack;sda_o=#11,b;/产生应答信号beginrw=#1srO;#2;if(debug&rw)Sdisp1ay(,DEBUGi2cs1ave;commandbytereceived,$time);if(debug&.!rw)Sdisp1ay(z,DEBUGi2c_s1ave;commandbytereceived(read)at%t”(write)at%t,$time);beginif(debug)#2Sdisp1ayCDEBUGi2c_s1ave;addres
14、s%x,mem_do,mem.#2Sdisp1ayCDEBUGi2c_s1ave;2=%x*,mem4,h,mem4,h1,ends1ave_ack:if(rw)state=#1data;memdo7;e1seId=#11,b1;if(rw)memdo=datab1ockreadadr);memcheck0=%x,mem4,h2);endbeginbeginendstate=#1#1memmem_adr;begin%xfromendsdao=#1getmemadr;endet_mem_adr:/等待内存地址beginmem_adr=#1sr;/保存内存地址if(acc_done)state=#1gma_ack;sda_o=#1!(sr=15);/收到合法地址信号后发出应答信号if(debug)#1Sdisp1ay(zzDEBUGi2c_s1ave;address,sr,sda_o);received,endadr=%x,ack=%b”gma_ack:state=#1