小梅哥课程学习——串口发送应用之发送数据(可在vivado中仿真出现正确波形)
//1、底层代码源代码发送10位数据
module uart_pr(
clk,
reset_n,
send_go,
data,
baud_set,
tx_done,
uart_tx
);
input clk;
input reset_n;
input send_go;
input [7:0]data;
input [2:0]baud_set;
output reg tx_done;
output reg uart_tx; //再书写关于bps_DR的选择计算
reg [17:0] bps_DR;
always@(*)
case(baud_set)
0:bps_DR=50000000/9600;
1:bps_DR=50000000/19200;
2:bps_DR=50000000/38400;
3:bps_DR=50000000/57600;
4:bps_DR=50000000/115200;
default:bps_DR=50000000/9600;
endcase
reg send_en;
always@(posedge clk or negedge reset_n)
if(!reset_n)
send_en<=0;
else if(send_go)//记住这边只能用顶层的计数counter,不能用底层的div_cnt以及bps_cnt;
send_en<=1;
else if(tx_done)
send_en<=0; //存储数据
reg [7:0]r_data;
always@(posedge clk or negedge reset_n)//这里为什么不需要复位的下降沿
if(!reset_n)
r_data<=0;
else if(send_go)
r_data<=data;
else
r_data<=r_data;
//首先书写对应波特率的计数,分频div_cnt
//根据最低的波特率来确定div_cnt的宽度
reg [17:0]div_cnt;
always@(posedge clk or negedge reset_n)
if(!reset_n)
div_cnt<=0;
else if(send_en)begin
if(div_cnt==bps_DR-1)
div_cnt<=0;
else
div_cnt<=div_cnt+1'b1;
end
else
div_cnt<=0; wire bps_clk;
assign bps_clk=(div_cnt==1);
//开始书写下一个计数bps_cnt,来实现10为数据的发送
reg [3:0] bps_cnt;
always@(posedge clk or negedge reset_n)
if(!reset_n)
bps_cnt<=0;
else if(send_en)begin
if(bps_clk)begin
if(bps_cnt==11)
bps_cnt<=0;
else
bps_cnt<=bps_cnt+1'b1;
end
end
else
bps_cnt=0;
//开始书写发送10位的数据
always@(posedge clk or negedge reset_n)
if(!reset_n)
uart_tx<=1;
else case(bps_cnt)
1:uart_tx<=0;
2:uart_tx<=r_data[0];
3:uart_tx<=r_data[1];
4:uart_tx<=r_data[2];
5:uart_tx<=r_data[3];
6:uart_tx<=r_data[4];
7:uart_tx<=r_data[5];
8:uart_tx<=r_data[6];
9:uart_tx<=r_data[7];
10:uart_tx<=1;
11:uart_tx<=1;
default:uart_tx<=1;
endcase always@(posedge clk or negedge reset_n)
if(!reset_n)
tx_done<=0;
else if((bps_cnt==10)&&(bps_clk==1))
tx_done<=1;
else
tx_done<=0;
endmodule
//2、底层代码仿真文件
`timescale 1ns / 1ps
module uart_pr_tb();
reg clk;
reg reset_n;
reg send_en;
reg [7:0]data;
reg [2:0]baud_set;
wire tx_done;
wire uart_tx;
uart_pr uart_pr_tb(
.clk(clk),
.reset_n(reset_n),
.send_en(send_en),
.data(data),
.baud_set(baud_set),
.tx_done(tx_done),
.uart_tx(uart_tx)
);
initial clk=1;
always#10 clk=!clk; initial begin
reset_n=0;
data=0;
send_en=0;
baud_set=4;
#201;
reset_n=1;
#20;
data=8'h57;
send_en=1;
@(posedge tx_done)
send_en=0;
#2000;
data=8'h75;
send_en=1;
@(posedge tx_done)
send_en=0;
#20000;
$stop;
end endmodule
3、顶层代码源文件
//每10ms以115200的波特率发送一个数据,每次发送的
//数据比前一个数据大一(计数器)
//顶层设计模块
module uart_test1(
clk,
reset_n,
uart_tx
);
input clk;
input reset_n;
output uart_tx; reg send_go;//这是顶层的send_en放在下面会出错
reg [7:0] data;
//先将发送10位数据的uart进行例化
uart_pr uart_pr_inst0(
.clk(clk),
.reset_n(reset_n),
.send_go(send_go),
.data(data),
.baud_set(3'd4),
.tx_done(tx_done),
.uart_tx(uart_tx)
);
//先写出一个10ms的计数器
reg [18:0]counter;
always@(posedge clk or negedge reset_n)
if(!reset_n)
counter<=0;
else if(counter==499999)
counter<=0;
else
counter<=counter+1'b1;
//书写发送信号send_en
//底层不是控制过send_en了吗??怎么这里还写控制send_en
//因为底层控制send_en在testbench中控制的,最后不会在板级验证的时候起作用
//那只在testbench中也就是仿真波形中会出现。
always@(posedge clk or negedge reset_n)
if(!reset_n)
send_go<=0;
else if(counter==1)//记住这边只能用顶层的计数counter,不能用底层的div_cnt以及bps_cnt;
send_go<=1;
else //设置send_go的时候一定要注意,什么时候开始,什么时候结束要形成闭环。
send_go<=0;//else还是要加,只不过不用带tx_done因为tx_done已经在顶层模块说明过了
//书写data的每次加1;
always@(posedge clk or negedge reset_n)
if(!reset_n)
data<=0;
else if(tx_done)
data<=data+1'b1;
endmodule
4、顶层代码仿真文件
`timescale 1ns / 1ps
module uart_test1_tb();
reg clk;
reg reset_n;
wire uart_tx;
uart_test1 uart_test1_inst0(
.clk(clk),
.reset_n(reset_n),
.uart_tx(uart_tx)
); initial clk=1;
always #10 clk=!clk; initial begin
reset_n=0;
#201;
reset_n=1; #50000000;
$stop; end
endmodule
小梅哥课程学习——串口发送应用之发送数据(可在vivado中仿真出现正确波形)的更多相关文章
- 【小梅哥SOPC学习笔记】SOPC开发常见问题及解决办法集锦
SOPC开发常见问题及解决办法集锦 一.Symbol 'NULL' could not be resolved 近期在评估使用NIOS II处理器进行项目的开发,我使用的软件是Quartus II 1 ...
- 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II
SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...
- 【小梅哥SOPC学习笔记】切换NIOS II CPU的主内存后软件中需要注意的几点设置
切换NIOS II CPU的主内存后软件中需要注意的几点设置 有时候,我们可能面对这样一种情况: 1. 我们创建一个SOPC系统,并在QSYS中设置NIOS II的复位地址和异常地址都指向SRAM: ...
- 【小梅哥SOPC学习笔记】系统时钟的使用
给NIOS II CPU添加一颗澎湃的心——系统时钟的使用 本实验介绍如何在Qsys中添加一个定时器作为NIOS II的心跳定时器,并在NIOS II中软件编程使用该定时器. 将上一个实验watchd ...
- 【小梅哥SOPC学习笔记】sof与NIOS II的elf固件合并jic得到文件
sof与NIOS II的elf固件合并jic得到文件 注意,本方法已经有更加简便的方法,小梅哥提供相应的脚本文件,可以一键生成所需文件,脚本请前往芯航线FPGA技术支持群获取. 7.1 为什么需要将S ...
- 【小梅哥SOPC学习笔记】NIOS II工程目录改变时project无法编译问题
解决NIOS II工程移动在磁盘上位置后project无法编译问题 说明:本文档于2017年3月4日由小梅哥更新部分内容,主要是增加了讲解以Quartus II13.0为代表的经典版本和以15.1为代 ...
- 【小梅哥SOPC学习笔记】设置Eclipse在编译(build)前自动保存源代码文件
设置Eclipse在编译(build)前自动保存源代码文件 Eclipse 常用设置之让Eclipse在编译(build)前自动保存源代码文件 一.让Eclipse在编译(build)前自动保存源代码 ...
- 【小梅哥SOPC学习笔记】给NIOS II CPU增加看门狗定时器并使用
给NIOS II CPU增加看门狗定时器并使用 配置看门狗定时器: 1. 设置计时溢出时间为1秒 2. 计数器位宽为32位 3. 勾选No Start/Stop control bits 4. 勾选F ...
- 【小梅哥SOPC学习笔记】Altera SOPC嵌入式系统设计教程
Altera SOPC嵌入式系统设计教程 第1章 概述 SOPC(System On Programmable Chip,可编程的片上系统)是Altera公司提出来的一种灵活.高效的SOC解决方案.它 ...
- Python学习笔记_从CSV读取数据写入Excel文件中
本示例特点: 1.读取CSV,写入Excel 2.读取CSV里具体行.具体列,具体行列的值 一.系统环境 1. OS:Win10 64位英文版 2. Python 3.7 3. 使用第三方库:csv. ...
随机推荐
- win11恢复完整右键菜单
使用注册表修改 首先,通过修改注册表,我们就可以将 Win11 的右键菜单改为老样式.下面是具体的方法. 运行"regedit",开启注册表编辑器,定位到"HKEY_CU ...
- .Net的产品变迁
从开始接触.Net以来,转眼过了好几年.在这许多年里,不得不感慨.Net产品线也在不断发生着变化, 下面就简单的进行一下梳理. .Net能做桌面应用程序,也就是C/S,也能做网站开发,就是通常说的B/ ...
- uniapp全局黑白
page{filter: grayscale(100%); } .uni-tabbar__item{filter: grayscale(100%); }
- Redis缓存雪崩,击穿和穿透
这三个问题的发生,会导致大量的请求直接积压到数据库,如果并发量很大,则可能会导致数据库宕机或故障. 缓存雪崩 描述:大量的请求无法在redis缓存中进行处理而被发送到数据库,导致数据库压力陡增. ...
- 一些test短代码
#include <stdio.h> int main(){ char ray_tx_pwr[2][3]={{1,2,3},{4,5,6}}; int i = 0; printf(&quo ...
- Vue 更改数组中的值,页面不刷新问题。解决方法+原理说明
一.Vue 更改数组中的值,页面不刷新问题 data{ hobby:["打游戏","想静静","发呆"] } 1.错误写法(页面不刷新): ...
- Winform使用CefSharp和HttpWebRequest如何保持会话Session
之前我们使用CefSharp,在Winform中,使用ChromiumWebBrowser加载了web项目的页面.并且通过html页面的js调用了本地的窗口.那么下一个问题来了.为了保障系统安全性,项 ...
- 一个严谨的STM32串口DMA发送接收机制
关键点: 1.一个半接收机制 2.一个是寄存器的操作顺序 参考链接: https://www.eet-china.com/mp/a167050.html
- JS学习-Promise
Promise 一个 Promise 必然处于以下几种状态之一: 待定(pending): 初始状态,既没有被兑现,也没有被拒绝. 已兑现(fulfilled): 意味着操作成功完成. 已拒绝(rej ...
- PLSQL REPLACE 函数替换操作
oracle REPLACE 函数是用另外一个值来替代串中的某个值. 例如,可以用一个匹配数字来替代字母的每一次出现. REPLACE 的格式如下: REPLACE ( char, search_st ...