本次设计源码地址:http://download.csdn.net/detail/noticeable/9914173

实验现象:通过串口将数据发送到FPGA 中,通过quartus II 提供的in system memory content editor 工具查看RAM中接收到的数据,当需要是,按下按键KEY0,将FPGA 的RAM 中存储的数据通过串口发送出去。

知识点:

    (1)存储器IP核的使用(2)in system memory content editor 内存查看工具的使用

系统结构框图如下,如何绘制在http://www.cnblogs.com/noticeable/p/7248404.html可以进行查看

设计过程:复制之前写的uart工程,打开,添加menmoryIP核

然后直接next,直到finish,此时就可以将IP核添加完毕了。

直接将IP核生成的文件设置为顶层文件,编写testbench文件对其进行仿真

`timescale 1ns/1ns
`define clock_period module dua_ram_tb;
reg clock;
reg [:]data;
reg [:]rdaddress;
reg [:]wraddress;
reg wren;
wire [:]q;
integer i;
dua_ram dua_ram0(
.clock(clock),
.data(data),
.rdaddress(rdaddress),
.wraddress(wraddress),
.wren(wren),
.q(q)
);//端口连接 initial clock=;
always#(`clock_period/)clock=~clock; initial begin
data=;
rdaddress=;
wraddress=;
wren=;
#(`clock_period*+);
for(i=;i<=;i=i+)begin // 写操作
wren=;
data=-i;
wraddress=i;
#(`clock_period);
end
wren=;
#(`clock_period*+);//延迟一段时间后进行读操作
for(i=;i<=;i=i+)begin // 读操作
rdaddress=i;
#(`clock_period);
end
#;
$stop;
end
endmodule

设置仿真脚本,点击仿真,进行前仿

仿真完了,可以对双口RAM有一个基本了解了,下面就将其添加到之前写的uart工程中

新建一个uart_dpram.v文件,并设置其为顶层文件,代码按照结构图进行编辑如下:

module uart_dpram(
clk,
rst_n,
key_in,
rs232_rx,
rs232_tx);
input clk;
input rst_n;
input key_in;
input rs232_rx; //串口读取端口
output rs232_tx; //串口写出端口 wire key_flag; //按键检测标志
wire key_state; //按键状态标志
wire rx_done; //读取完成标志
wire tx_done; //写出完成标志
wire send_en; //写出使能
wire [:]rdaddress,wraddress; //读地址和写地址
wire wren; //写入使能
wire [:]rx_data,tx_data; //待读取数据与发送数据 uart_tx uart_tx_a(
.clk(clk),
.rst_n(rst_n),
.send_en(send_en),
.baud_set('d0),
.tx_done(tx_done),
.rs232_tx(rs232_tx),
.data_byte(tx_data),
.uart_state()
); uart_rx uart_rx_a(
.clk(clk),
.rs232_rx(rs232_rx),
.baud_set('d0),
.rst_n(rst_n),
.data_byte(rx_data),
.rx_done(rx_done)
);
key_filter key_filter_a(
.clk(clk),
.rst_n(rst_n),
.key_in(key_in),
.key_flag(key_flag),
.key_state(key_state)
); dua_ram dua_ram_a(
.clock(clk),
.data(rx_data), //存储器入口是读取的数据
.rdaddress(rdaddress),
.wraddress(wraddress),
.wren(wren),
.q(tx_data) //存储器的出口是要写出的数据
);//端口连接
ctrl ctrl_a(
.clk(clk),
.rst_n(rst_n),
.key_flag(key_flag),
.key_state(key_state),
.rx_done(rx_done),
.tx_done(tx_done),
.rdaddress(rdaddress),
.wraddress(wraddress),
.wren(wren),
.send_en(send_en)
); endmodule

如代码中所说,ctrl模块没有定义,编译肯定是会报错的,下面继续编写ctrl 模块,新建一个ctrl.v文件,编辑如下:

module ctrl(
clk,
rst_n,
key_flag,
key_state,
rx_done,
tx_done,
rdaddress,
wraddress,
wren,
send_en
);//控制模块 input clk;
input rst_n;
input key_flag;
input key_state;
input rx_done;
input tx_done;
output reg[:]rdaddress;
output reg[:]wraddress;
output wren; //写入使能信号
output reg send_en; //发送使能 assign wren=rx_done; //读取完成的信号即可以写入了
reg do_send; //发送标志
reg r0_send_done,r1_send_done; //发送缓冲寄存器 always@(posedge clk or negedge rst_n)//写地址
if(!rst_n)
wraddress<='d0;
else if(rx_done) //每读取完一次,写入地址+1
wraddress<=wraddress+'d1;
else
wraddress<=wraddress; always@(posedge clk or negedge rst_n)
if(!rst_n)
do_send<=;
else if(key_flag&&!key_state) //如果按键按下一次,发送状态改变一次
do_send<=~do_send; always@(posedge clk or negedge rst_n)//读地址
if(!rst_n)
rdaddress<='d0;
else if(do_send&&tx_done) //发送状态为发送,且1byte数据已经发送完成了,则读地址+1
rdaddress<=rdaddress+'d1; always@(posedge clk or negedge rst_n)///ram读有两拍的延迟,所以加两级寄存器对发送使能进行缓存
if(!rst_n) begin
r0_send_done<='b0;
r1_send_done<='b0;
end
else begin
r0_send_done<=(do_send&&tx_done);
r1_send_done<=r0_send_done;
end always@(posedge clk or negedge rst_n)//发送使能
if(!rst_n)
send_en<=;
else if(key_flag&&!key_state)
send_en<='b1;
else if(r1_send_done)
send_en<=;
else
send_en<=; endmodule

编写testbench文件进行仿真,将test9中的keymodule 复制到本工程的testbench文件夹下,并添加到工程中

`timescale 1ns/1ns
`define clock_period
module uart_dpram_tb;
reg clk;
reg rst_n;
wire key_in;
wire rs232_rx;
wire rs232_tx;
wire tx_done;
reg [:]data_byte_t;
reg send_en;
wire [:]baud_set;
reg press; assign baud_set = 'd0;
uart_dpram uart_dpram_1(
.clk(clk),
.rst_n(rst_n),
.key_in(rst_n),
.rs232_rx(rs232_rx),
.rs232_tx(rs232_tx)); uart_tx uart_tx1(
.clk(clk),
.rst_n(rst_n),
.send_en(send_en),
.baud_set(baud_set),
.tx_done(tx_done),
.rs232_tx(rs232_rx),
.data_byte(data_byte_t),
.uart_state()
); key_module key_module1(
.press(press),
.key(key_in)
);
initial clk=;
always#(`clock_period/) clk=~clk;
//发送数据
initial begin
rst_n = 'b0;
press = ;
data_byte_t = 'd0;
send_en = 'd0;
#(`clock_period*+)
rst_n='b1;
#(`clock_period*+) data_byte_t<='haa;
send_en<='d1;
#(`clock_period)
send_en<='d0; @(posedge tx_done)//等待传输完成的上升沿 #(`clock_period*)//重新发送
data_byte_t<='h55;
send_en<='d1;
#(`clock_period)
send_en<='d0;
@(posedge tx_done)//等待传输完成的上升沿
#(`clock_period*)//重新发送
data_byte_t<='hcc;
send_en<='d1;
#(`clock_period)
send_en<='d0; @(posedge tx_done)//等待传输完成的上升沿
#(`clock_period*)//重新发送
data_byte_t<='hff;
send_en<='d1;
#(`clock_period)
send_en<='d0; //按下按键读取发送出去的内容
@(posedge tx_done) #(`clock_period*); press = ;
#(`clock_period*)
press = ;
#(`clock_period*); end
endmodule

添加路径如下:

点击仿真,仿真结果如下

引脚配置,烧写程序,进行扳级验证,这里GPIO0_D0连接到USB_TTL的TXD,GPIO0_D1连接到USB_TTL 的RXD即可。

打开串口调试软件,连接USB-TTL模块,发送数据,按下按键KEY_1,FPGA不断把刚才发到ram中的数据读取出来,再按一下,停止发送,效果图如下所示

用嵌入式块RAM IP核配置一个双口RAM的更多相关文章

  1. 第7讲 SPI和RAM IP核

    学习目的: (1) 熟悉SPI接口和它的读写时序: (2) 复习Verilog仿真语句中的$readmemb命令和$display命令: (3) 掌握SPI接口写时序操作的硬件语言描述流程(本例仅以写 ...

  2. SPI和RAM IP核

    学习目的: (1) 熟悉SPI接口和它的读写时序: (2) 复习Verilog仿真语句中的$readmemb命令和$display命令: (3) 掌握SPI接口写时序操作的硬件语言描述流程(本例仅以写 ...

  3. 7 Series GTP IP核使用总结 IP核配置篇

    FPGA内嵌收发器相当于以太网中的PHY芯片,但更灵活更高效,线速率也在随着FPGA芯片的发展升级.本文对7系列FPGA内部高速收发器GTP IP核的配置和使用做些简单的总结,以备后续回顾重用.本文是 ...

  4. 单口 RAM、伪双口 RAM、真双口 RAM、单口 ROM、双口 ROM 到底有什么区别呢?

    打开 IP Catalog,搜索 Block Memory Generator,即可看到其 Memory Type 可分为 5 中,分别是单口 RAM(Single Port RAM).伪双口 RAM ...

  5. 双口RAM,值得研究

    在FPGA设计过程中,使用好双口RAM,也是提高效率的一种方法. 官方将双口RAM分为简单双口RAM和真双口RAM. 简单双口RAM只有一个写端口,一个读端口. 真双口RAM分别有两个写端口和两个读端 ...

  6. FMC与FPGA双口ram通讯

    硬件环境:ARM+FPGA通过FMC互联,STM32F767和 EP4CE15F23I7 FMC设置,STM的系统时钟HCLK为216MHz /* FMC initialization functio ...

  7. 单口RAM、双口RAM、FIFO

    单口与双口的区别在于,单口只有一组数据线与地址线,因此读写不能同时进行.而双口有两组数据线与地址线,读写可同时进行.FIFO读写可同时进行,可以看作是双口.    双口RAM分伪双口RAM(Xilin ...

  8. 【iCore1S 双核心板_FPGA】例程十七:基于双口RAM的ARM+FPGA数据存取实验

    实验现象: 核心代码: module DUAL_PORT_RAM( input CLK_12M, inout WR, input RD, input CS0, :]A, :]DB, output FP ...

  9. xilinx IP核配置,一步一步验证Xilinx Serdes GTX最高8.0Gbps

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/u010161493/article/details/77658599   目录(?)[+]   之前 ...

随机推荐

  1. Spring整体了解

      1.spring原理 内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建.调用对象,Spring就是 ...

  2. !!!常用SVG代码

    http://www.w3school.com.cn/svg/svg_examples.asp svg实例 http://www.w3school.com.cn/svg/svg_reference.a ...

  3. 面试回顾——session相关

    原地址:https://blog.csdn.net/quiet_girl/article/details/50580095 Session结束生命周期的几种情况: (1)客户端关闭浏览器(只针对ses ...

  4. Mybatis-spring 传统dao开发

    jdbc.properties jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis?chara ...

  5. 渲染函数render和函数式组件

    vnode对象 vnode对象包括(vnode并不是vue实例,而是vue实例中渲染函数render执行后生成的结果) this.tag = tag // 当前节点标签名 this.data = da ...

  6. JAVA 类的三大特性,封装,继承,多态 的一些发现总结

    < 一 > 封装 < 二 > 继承 1,关于父类中的私有属性和方法,子类能不能访问的问题 1.1,子类不能通过继承拥有父类的私有属性和方法 1.2,子类可以从父类继承下来的 方 ...

  7. tomcat 部署swagger 请求到后端乱码

    问题: @ApiOperation(value = "", notes = "查看关键词列表") @ResponseBody @RequestMapping(v ...

  8. centos 7设置本地yum资源库

    前言 同样的,是在这两天安装ambari的时候遇到的问题之一,那就是关于centos的本地yum源的制作,当时是一种是制作iso镜像的yum源,还有一种将rpm软件包打成压缩包上传到centos的某一 ...

  9. POI richText和html的转换案例

    private XSSFRichTextString parseHtmlStrToRichText(String htmlStr) { Document document = parseHtmlStr ...

  10. SQL Server中使用数据库快照的方式来完成测试环境中数据库的轻量级备份还原操作

    在开发或者测试环境的数据库中,经常会发现有开发或者测试人员误删除表或者数据的情况,对于开发或者测试库,一般都没有安排定时的备份任务去备份数据库,一方面是由于存储资源有限,不太可能给开发或者测试环境准备 ...