用户工具

站点工具


icore3_fpga_19

差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

上一修订版 两侧同时换到之后的修订记录
icore3_fpga_19 [2019/12/23 17:45]
zhangzheng 创建
icore3_fpga_19 [2020/02/27 18:34]
zgf
行 1: 行 1:
-[[http://www.cnblogs.com/xiaomagee/p/5642334.html]]+|  **银杏科技有限公司旗下技术文档发布平台** ​ |||| 
 +|技术支持电话|**0379-69926675-801**||| 
 +|技术支持邮件|Gingko@vip.163.com||| 
 +|技术论坛|http://www.eeschool.org||| 
 +^  版本 ​ ^  日期 ​ ^  作者 ​ ^  修改内容 ​ ^ 
 +|  V1.0  |  2020-02-27 ​ |  gingko ​ |  初次建立 ​ |  
 + 
 +===== 实验十九:基于双口 RAM 的 ARM+FPGA 数据存取实验 ===== 
 +  
 +==== 一、 实验目的与意义 ==== 
 +  
 +  - 了解双口 RAM 读写的工作原理。 
 +  - 掌握双口 RAM 使用方法。 
 +  - 掌握 QuartusII 集成开发环境使用方法。 
 +二、 实验设备及平台  
 +  - iCore3 双核心板。[[https://​item.taobao.com/item.htm?​id=524229438677|点击购买]] 
 +  - Blaster(或相同功能)仿真器和 USB 线缆。[[https:​//item.taobao.com/​item.htm?​id=554869837940|点击购买]] 
 +  - Micro USB 线缆。 
 +  - QuartusII 开发平台。 
 +  - Keil MDK 开发平台。 
 +  - 装有 WIN XP(及更高版本)系统的计算机。  
 +==== 三、 实验原理 ==== 
 +  
 +  * 由于双口RAM有两条相互独立的地址线、数据线和控制线,能实现数据共享,本实验针对双口 RAM 的工作特点进行实验验证。实验中通过 FPGA 对 RAM 的 A 端口进行读写操作,RAM的A端口先向RAM中写入0到255的数据,然后再读出来,如此循环操作。同时,通过 Commix 向 STM32 发送读命令,STM32收到命令后,通过STM32F407的 FSMC总线实现与FPGA通信,对RAM的 B 端口进行读控制,发送一次读命令RAM的 B 端口把相应地址里面的数据发送至 ARM,再发送至 Commix 显示出来以验证实验的成功性。 在本实验中实现了双口 RAM 的两种工作模式:​1、双口 RAM 一个端口写操作,另一个端口 读操作;2、双口 RAM 两个端口同时读操作。实验的原理如下图 1 所示。 
 +{{ :​icore3:​icore3_fpga_19_1.png?​direct |实验原理图}}  
 + 
 +==== 四、 Quartus 内部双口 RAM 块调用 ==== 
 +  
 +1、 打开 Tools——MegaWizard Plug-In Manager. 
 +{{ :​icore3:​icore3_fpga_19_2.png?​direct |图1}}  
 +2、创建IP核,点击next。 
 +{{ :​icore3:​icore3_fpga_19_3.png?​direct |图2}}  
 +3、在弹出界面1存储器列表里选择2双口RAM。3处选择FPGA类型。4处选择输出文件语言类型。5处设置文件存储位置和命名。点击6处next进行下一项设置。 
 +{{ :​icore3:​icore3_fpga_19_4.png?​direct |图3}}  
 +4、设置如下 
 +{{ :​icore3:​icore3_fpga_19_5.png?​direct |图4}}  
 +5、设置存储器深度为256,输出总线宽度16bit,使用FPGA逻辑资源类型选择自动分配。点击next。 
 +{{ :​icore3:​icore3_fpga_19_6.png?​direct |图5}}  
 +6、配置端口时钟和读使能信号。 
 +{{ :​icore3:​icore3_fpga_19_7.png?​direct |图6}}  
 +7、注意红框中不打勾,点击Next,​ 
 +{{ :​icore3:​icore3_fpga_19_8.png?​direct |图7}}  
 +8、后面几项保持默认设置,直接点击Next,最后点击Finish,双口RAM就构建好了。注意:在存储内容初始化选项设置里选择保持空白,因为本实验是要向双口RAM中写入数据再读出数据并进行对比的操作,不需要在存储器内预装数据。 
 +{{ :​icore3:​icore3_fpga_19_9.png?​direct |图8}}  
 +{{ :​icore3:​icore3_fpga_19_10.png?​direct |图9}}  
 +{{ :​icore3:​icore3_fpga_19_11.png?​direct |图10}}  
 +{{ :​icore3:​icore3_fpga_19_12.png?​direct |图11}}  
 +==== 五、代码讲解 ==== 
 +  * 构建工程并添加好双口RAM核后,就可以进行逻辑功能的编写了。本实验要实现双口RAM的两种工作模式,这里分别讲一下两种工作模式的实现流程和方法。 
 +  * 模式1:由FPGA控制,先通过A端口向RAM中写入256个数据,然后读出来,循环操作。这是对A端口的独立读写操作。 
 +  * 为了进行数据的对比操作,存储的数据值跟其地址一样,通过计数生成存储数据,并将数据存入与其地址一样的存储单元。计数器以记满512个数为一个周期,前256个时钟周期内向RAM中顺序写入数据,后256个时钟周期内从RAM中顺序读取数据。代码如下: 
 +<code verilog>​ 
 + always @ (posedge a_clk or negedge rst_n) 
 + begin 
 + if(!rst_n) 
 +    ​begin 
 + a_wren <= 1'​d0;​ 
 + a_rden <= 1'​d0;​ 
 + a_datain <= 10'​d0;​ 
 + a_addr <= 10'​d0;​ 
 +    end  
 + else if(cnt >= 10'd0 && cnt <​=10'​d255) 
 + begin 
 + a_wren <= 1'​d1; ​          //​写使能信号拉高 
 + a_addr <= cnt;​ //​写地址 
 + a_datain <= cnt;​ //​写入数据 
 + a_rden <= 1'​d0;​ //​读使能信号拉低 
 + end  
 + else if(cnt >= 10'​d256 && cnt <= 10'​d511) 
 + begin 
 + a_rden <= 1'​d1;​ //​读使能信号拉高 
 + a_addr <= cnt - 10'​d256;​ //​读地址 
 + a_wren <= 1'​d0;​ //​写使能信号拉低 
 + end 
 + end 
 +</​code>​ 
 +  * FPGA读取数据之后,对读取器数据和其存储地址进行比对,并根据对比结果产生错误提示信号,再以此信号控制FPGA_LED的显示颜色。  
 +  * 模式2:在FPGA对RAM进行读写操作的同时,STM32通过FSMC总线对RAM的B端口进行读操作。实现对RAM的双端口读操作。 
 +  * 当STM32从RAM中读取数据时,相当于STM32通过FSMC总线对外部存储器进行操作,因此,检测FSMC传递至FPGA的读信号,并将RAM的值从B端口输出至FSMC总线,实现STM32对RAM的读功能。代码如下: 
 +<code verilog>​ 
 +//​--------------------------ram_b_rd---------------------------//​ 
 +/​*控制ram_b端口的读取功能,当读信号来临时,读取相应的数据发送至fsmc总线*/​ 
 + wire rd = (CS0 | RD); //​提取读信号 
 + wire wr = (CS0 | WR);    //​提取写信号 
 +  
 + reg wr_clk1,​wr_clk2;​ 
 + always @(posedge PLL_100M or negedge rst_n) 
 + begin 
 + if(!rst_n) 
 + begin 
 + wr_clk1 <= 1'​d1;​ 
 + wr_clk2 <= 1'​d1;​ 
 + end 
 + else 
 + {wr_clk2,​wr_clk1} <= {wr_clk1,​wr};​  
 + end 
 + 
 +    wire b_clk = (!wr_clk2 | !rd);​ //​提取ram_b端口的时钟 
 +    assign DB = !rd ? b_dataout : 16'​hzzzz;​ //​读信号来临,读取ram_b端口数据 
 +</​code>​ 
 +  * 在代码中,对时钟做了延迟处理,以保证时钟的触发沿位于数据的稳定期,具体实现可以参考例程代码。 
 + 
 +==== 六、 实验步骤 ==== 
 +  
 +  - 把仿真器与 iCore3 的 SWD 调试口连接(直接相连或者通过转换器相连);  
 +  - 将 USB-Blaster 与 iCore3 的 JTAG 调试口相连;  
 +  - 将跳线帽插在 USB UART;  
 +  - 把 iCore3(USB_UART)通过 Micro USB 线与计算机连接,为 iCore3 供电;  
 +  - 打开 Commix 串口精灵,找到对应的 COM 端口打开;  
 +  - 打开 Quartus II 开发环境,并打开实验工程;  
 +  - 烧写 FPGA 程序到 iCore3 上;  
 +  - 打开 Keil MDK 开发环境,并打开实验工程;  
 +  - 烧写 ARM 程序到 iCore3 上;  
 +  - 输入串口命令,观察实验现象。  
 +==== 七、 实验现象 ====  
 +  * 一方面,观察 FPGA_LED 的颜色,FPGA向RAM 中先写如数据,然后再读出来,读出数据与其地址相等,绿灯长亮。否则,红灯亮。  
 +  * 另一方面,通过 Commix 发送读命令读取 RAM 地址中的数据,对比写入数据与读取的数据,可以知道写入与读取的数据相同。  
 +  * **命令格式**: 读命令:ram+空格+read+空格+address+\cr\lf ​          
 +    * 例如:ram read 123\cr\lf  
 +    * 解析:读取 ram 的第 123 地址的数据。 
 + 
icore3_fpga_19.txt · 最后更改: 2022/03/18 15:45 由 sean