《双口RAM概述及Vivado RAM IP核应用.docx》由会员分享,可在线阅读,更多相关《双口RAM概述及Vivado RAM IP核应用.docx(14页珍藏版)》请在第一文库网上搜索。
1、双口RAM概述及ViVadoRAMIP核应用1. 双口RAM概述双RAM(dua1portRAM)在异构系统中应用广泛,通过双口RAM,不同硬性架构的皿可以实现数据的交互,从而实现通值。例如,一般情况下,ARM与DSP之间的通信,可以利用双口RAM实现,ARM通过EBI总线连接到双口RAM的A,DSP通过EMIF总线(也可以是UPP总线,取决于速度需求)连接到双RAM的B口,两者对同一块存储区域进行操作,即可实现两者的数据交互。但是,因为双口RAM的A口和B都可以对相同的内存地址进行操作,这就引出了一个问题一一假如通信双方在两个端旦对同一地址同时读写,就会引发冲突。要解决这个问题,办法有二。一
2、是通信双方在时序上保证不会同时读写同一地址,将ARM和DSP可写地址范围进行分区,无论任何一方写完数据后都通过IO发送中断通知对方,对方进行数据读取(乒乓RAM操作),这样是比较可靠的;另外一个办法就是在fpga里设置写busy信号,实现两端写同步:O在FPGA中,构建双口RAM可以通过两种方法,一种是利用distribu拄dRAM构建,另一种是利用B1OCkRAM构建,关于两者的具体区别,可以参考这两篇文章口口。简而言之,B1ockRAM是是使用FPGA中的整块双口RAM资源,而distributedRAM则是用FPGA中的逻辑资源拼凑形成的。一般的原则是,较大的存储应用,建议用bram;零
3、星的小ram,一般就用dram。在ViVado中,RAMIPMemories&StrorageE1ementsRAM&RoMS和RAM&ROM&BRAM文件夹下,如回丽示,下面简要介绍一下ViVado的而hRAMIP核。(图1.1)2. Vivado双口RAMIP核3. 1B1ockMemoryGenerator概述点击图1.1的B1ockMemoryGenerator项,利用BRAM来构建双口RAM。B1ockMemoryGenerator窗口如图2.1所示。图中,第1部分,在IPsymbo1选项卡,点击号可以展开端口具体信号,如图2.2所示。第2部分,ComponentNanIe可以设置I
4、P核的名字。第3部分,BaSiC选项卡,在MemoryTyPe下拉列表中,可以设置内存的类型,如图2.3所示。B1ockMemoryGnerator一共可以产生5种不同类型的内存空间,其中b1ockRAM有三种:单口RAM、简化双口RAM和真双口RAM。单口RAM只有一个端口(A端口),可以对A端口进行读写。简化双口RAM有两个端口(A和B端口),但是A端口只能进行写入操作,不能进行读出操作,而B端口则只能进行读出操作,不能进行写入操作。真双口RAM有两个端口(A和B端口),A和B端口都能进行读写操作口。(图2.1)(图2.2)(图2.3)2.2真双口RAM的设置2. 2.1Basic设置在B
5、asic选项卡的Memorytype选项中选择真双口RAM,IPSymbo1如图2.4所示。ECCOPIionS为默认设置,WriteEnabIe中也选择默认设置,不使能字节写,AIgorithmoPtionS选择默认设置。(图2.4)2 .2.2Port设置点击POrtAOPtionS选项卡,对A端口进行设置,设置WriteWidth为16(即RAM单元为16位),WriteWidth为1024(即内存深度为1024,该端口可读写的RAM单元有1024个),OPeratingMode(操作模式)一共有三种:WriteFirst,ReadFirst,NoChange0在WriteFirSt模式
6、中,在一个时钟周期里,莺入内存单元的数据被同步输出到输出数据总线上;在Reae1Fi嬴履式中,在一个时钟周期里,写入到内存单元的数据是当前输入数据总线上的数据,而输出到输出数据总线上的数据则是上一个时钟周期存储在内存单元中的数据。细节可参考PG058的49到50页4。Enab1ePortType设置为A1waysEnab1ed,一直使能端口A。其它设置使用默认设置。如图2.5所示。(图2.5)端口B设置为与A一致。在OtherOPtionS选项卡中,保留默认设置。1oadInitFiIe设置是否用Coe文件对内存区域初始化,这个在初始化RoM的时候会用到,这里不勾选,保持默认。最后,在SUmm
7、ar选项卡会显示消耗的资源。3 .双口RAM例程例程1,该例程是AItera官方例程口,采用盏播构建双口RAM,代码如下:moc1u1etrue_dpramsc1k(input7:0data_a,data_b,input5:0addr_a,addrb,inputwe_a,we_b,e1k,outputreg7:0q_a,q_b);/Dec1aretheRAMvariab1ereg7:0ram63:0;/PortAa1ways(posedgee1k)beginif(we_a)beginramaddra1=dataa;q_a二data_a;ende1sebeginq_a二ramaddr_a;end
8、end/PortBa1ways(posedgee1k)beginif(we_b)beginramaddrb=datab;q_b二data_b;ende1sebeginq_b=ramaddr_b;endendendmodu1e例程2,该例程是Xi1inX官方例程口,采用寄存器构建真双口RAM,代码如下:/Dua1-PortB1ockRAMwithTwoWritePorts/Fi1e:rams16.vmodu1ev_rams_16(c1ka,c1kb,ena,enb,weaweb,addraaddrb,dia,dib,doa,dob);inputc1ka,c1kb,ena,enb,wea,web;
9、input9:0addra,addrb;input15:0dia,dib;output15:0doa,dob;reg15:0ram1023:03;reg15:01doa,dob;a1ways(posedgec1ka)beginif(ena)beginif(wea)ramaddra=dia;doa二ramaddra;endenda1ways(posedgec1kb)beginif(enb)beginif(web)ramaddrb=dib;dob二ramaddrb;endendendmodu1e例程3,该例程是网友博客中的例程口,代码如下:moduIeTOP(inputUSER_C1Kdefine
10、D1Y#1regFPGEnab1e=O;reg3:0FPGA_Write_Enab1e=4h;reg31:0FPGA_Address=O;reg31:0FPGAJVrite_Data=0;reg31:0FPGAReadDatareg=O;wire31:0FPGA_Read_Data;reg10:0count=0;a1ways(posedgeUSER_C1K)begincount二count+1;if(count(=100)beginFPGA_Enab1e=0;FPGA_Write_Enab1e=4h;ende1seif(count=105)&(count100)beginFPGA_Enab1e
11、=1;FPGAJVrite_Enab1e二4hf;FPGAddress二FPGAAddress+4;FPGAJVrite_Data二FPGAJYrite_Data+1;ende1seif(count=110)&(count105)beginFPGA_Enab1e=0;FPGAJVrite_EnabIe=4h;FPGA_Address二0;FPGA_Write_Data=0;ende1seif(count=117)&(count110)beginFPGA_Enab1e=1;FPGAJVrite_Enab1e二4h;FPGA_Read_Data_reg=FPGA_Read_Data;FPGA_Ad
12、dress=FPGA_Address+4;ende1seif(count=118)beginFPGA_Enab1e=0;count=count;endendBBBByour_instance_name(.c1ka(USERC1k),/inputc1ka.ena(FPGA_Enab1e),/inputena.wea(FPGAJVrite_Enab1e),/input3:0wea.addra(FPGA_Address),/input31:0addra.dina(FPGAJVrite_Data),/input31:0dina.douta(FPGReadData),/output31:0douta.c
13、1kb(c1kb),/inputc1kb.enb(enb),/inputenb.web(web),/input3:0web.addrb(addrb),/input31:0addrb.dinb(dinb),/input31:0dinb.doutb(doutb)/output31:0doutb);endmodu1e该例程中,在CoUnt为101(100)后开始往地址4到20写入1-5,然后在CoUnt为I11(110)的时候读出写入的数据。4 .仿真下面利用Mode1SinI和Vivado进行联合仿真,关于vivado如何与mode1sim进行联合仿真可以存至篇文章:vivado与mode1sim
14、的关联以及器件库编译有一点要注意的是,我用的是ViVadO2017.1版本,这个版本只支持Mocie1sim1O.5及以上的版本,如果是低版本的Mode1sim,在用Vivado2017.1编译MOdeISim的仿真库时,会出错。ModeISim10.5版本可以在这里上越:mode1sim10.5适用vivado2017.1用ModeISim仿真时,会在sim_1/behav文件夹下产生3个.do文件,分别XXcompi1e,do,xx_simu1ate.do,xx_wave.do文件。在设计的VeriIog文件修派之后,如果在Mode1SinI中直接restart,仿真的其实还是没有修改前的
15、文件,要使修改的.V文件在Mode1sim中生效,可以在Mode1sim的命令窗口输入doxx_compi1e.do文件,对仿真的库文件以及设计文件(.v文件)重新编译,然后在输入doxx_simu1ate.do文件,才能仿真修改后的文件。输入doxx_compi1e.do命令对设计文件重新编译的时候,ModeISim会强制退出,这时由最后一句forcequit命令引起的,只要把它删掉就行了。如果要保存波形文件,可以SaVeformat,另存为XXwave,do文件。参考上面双口RAM的例程3进行功能仿真,RAMIP使用肛iteFirSt模式,设计文件代码如下:timesca1eIns/IpsIiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii