当前位置:网站首页>[FPGA] UART serial port_ V1.1
[FPGA] UART serial port_ V1.1
2022-06-27 05:19:00 【li_ lys】
UART A serial port _V1.1
The previous serial port was a little unstable, so I made this serial port , This serial port is applicable to various common baud rate settings , The principle of serial port is not explained here , Direct code sharing and input / output explanation .
One 、 Code
1.UART_RX
`timescale 1ns / 1ps
module uart_rx
#(parameter BPS =5208)
(
input clk ,
input rst_n ,
input din ,
output reg[7:0] dout /* synthesis syn_keep=1 */,
output reg dout_vld
);
//parameter BPS = 434;//115200 5208; //9600 Baud rate
reg [14:0] cnt0 ;
wire add_cnt0 ;
wire end_cnt0 ;
reg [ 3:0] cnt1 ;
wire add_cnt1 ;
wire end_cnt1 ;
reg rx0 ;
reg rx1 ;
reg rx2 ;
wire rx_en/* synthesis syn_keep=1 */;
reg flag_add ;
// Cross clock processing of data , Prevent metastable states
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
rx0 <= 1'b1;
rx1 <= 1'b1;
rx2 <= 1'b1;
end
else begin
rx0 <= din;
rx1 <= rx0;
rx2 <= rx1;
end
end
assign rx_en = rx2 & ~rx1;
// Falling edge detected , I.e. free bit from 1 Set as 0, Data transfer starts
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt0 <= 15'd0;
end
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 15'd0;
else
cnt0 <= cnt0 + 15'd1;
end
end
assign add_cnt0 = flag_add;
assign end_cnt0 = add_cnt0 && cnt0==(BPS-15'd1);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 4'd0;
end
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 4'd0;
else
cnt1 <= cnt1 + 4'd1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1==4'd9-4'd1 ; // Because it is a receiving program , The check bit is not set here , So you just need to receive the data , The last one 10 Bit must be bit stop bit , It can be ignored , Save resources
always @ (posedge clk or negedge rst_n)begin
if(!rst_n) begin
flag_add <= 1'b0;
end
else if(rx_en && flag_add==1'b0) begin
flag_add <= 1'b1;
end
else if(end_cnt1) begin
flag_add <= 1'b0;
end
end
always @ (posedge clk or negedge rst_n)begin
if(!rst_n) begin
dout <= 8'd0;
end
else if(add_cnt0 && cnt0==(BPS/2-1) && cnt1!=0) begin // Sample in the middle , At this time, the data is relatively stable , Sample from low to high
case(cnt1)
4'd1:dout[0]<=rx2;
4'd2:dout[1]<=rx2;
4'd3:dout[2]<=rx2;
4'd4:dout[3]<=rx2;
4'd5:dout[4]<=rx2;
4'd6:dout[5]<=rx2;
4'd7:dout[6]<=rx2;
4'd8:dout[7]<=rx2;
default:
;
endcase
end
else
;
end
// After transmitting the data signal
always @ (posedge clk or negedge rst_n)begin
if(!rst_n) begin
dout_vld <= 1'b0;
end
else if(end_cnt1) begin
dout_vld <= 1'b1;
end
else begin
dout_vld <= 1'b0;
end
end
endmodule
Module interface description
uart_rx
| Pin | A wide | Direction | explain |
|---|---|---|---|
| clk | 1 | IN | Module clock 50M |
| rst_n | 1 | IN | The low bit of the reset signal is valid |
| din | 1 | IN | RX data input |
| dout | 8 | OUT | Data output |
| dout_vld | 1 | OUT | Data output valid |
2.UART_TX
Here are some Inline code slice .
`timescale 1ns / 1ps
module uart_tx
#(parameter BPS =5208)
(
input clk ,
input rst_n ,
input [7:0] din ,
input din_vld,
output reg rdy ,
output byte_1 ,
output reg dout
);
//parameter BPS = 434;
reg [7:0] tx_data_tmp;
reg flag_add ;
reg [14:0] cnt0 ;
wire add_cnt0 ;
wire end_cnt0 ;
reg [ 3:0] cnt1 ;
wire add_cnt1 ;
wire end_cnt1 ;
wire [ 9:0] data ;
always @(posedge clk or negedge rst_n)begin
if(rst_n==1'b0)begin
flag_add <= 1'b0;
end
else if(flag_add==1'b0 && din_vld)begin
flag_add <= 1'b1;
end
else if(end_cnt1)begin
flag_add <= 1'b0;
end
end
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt0 <= 15'd0;
end
else if(add_cnt0)begin
if(end_cnt0)
cnt0 <= 15'd0;
else
cnt0 <= cnt0 + 15'd1;
end
end
assign add_cnt0 = flag_add;
assign end_cnt0 = add_cnt0 && cnt0==(BPS-15'd1);
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 4'd0;
end
else if(add_cnt1)begin
if(end_cnt1)
cnt1 <= 4'd0;
else
cnt1 <= cnt1 + 4'd1;
end
end
assign add_cnt1 = end_cnt0;
assign end_cnt1 = add_cnt1 && cnt1==4'd10-4'd1 ;
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
tx_data_tmp <=8'd0;
end
else if(flag_add==1'b0 && din_vld) begin
tx_data_tmp <= din;
end
end
always @ (posedge clk or negedge rst_n) begin
if(!rst_n) begin
dout <= 1'b1;
end
else if(add_cnt0 && cnt0==1-1)begin
dout<= data[cnt1];
end
end
assign data = {
1'b1,tx_data_tmp,1'b0}; // The transmission is from low to high data = { Stop bit , data [7], data [6] ~ data [0], Start bit };
always @( * )begin
if(din_vld || flag_add)
rdy = 1'b0;
else
rdy = 1'b1;
end
assign byte_1 = end_cnt1;
endmodule
Module interface description
uart_tx
| Pin | A wide | Direction | explain |
|---|---|---|---|
| clk | 1 | IN | Module clock 50M |
| rst_n | 1 | IN | The low bit of the reset signal is valid |
| din | 8 | IN | Send data input |
| din_vld | 1 | IN | Send data input valid |
| rdy | 1 | OUT | busy The signal 1: Not busy 0: busy |
| byte_1 | 1 | OUT | One byte transfer completion flag |
| dout | 1 | OUT | TX Data output |
Two 、 Summary note
Baud rate frequency division coefficient setting
parameter BPS =5208
Common baud rate 50M Clock frequency division coefficient
BAUD_9600 5208
BAUD_19200 2604
BAUD_38400 1302
BAUD_115200 434
busy Signal attention
always @( * )begin
if(din_vld || flag_add)
rdy = 1'b0;
else
rdy = 1'b1;
end
Here, combinatorial logic is used to effectively assign data to busy Signal busy status , It is recommended to use temporal logic to assign valid values to data inputs , Or use combinatorial logic to try to remove the significant bits here .
边栏推荐
- 机械转码日记【17】模板,STL简介
- 017 basics of C language: bit field and typedef
- 双位置继电器HJWS-9440
- 双位置继电器RXMVB2 R251 204 110DC
- Common programming abbreviations for orbit attitude
- 洛谷P4683 [IOI2008] Type Printer 题解
- Microservice system design - service fusing and degradation design
- Unity point light disappears
- Chapter 2 Introduction to key technologies
- Pytest框架的执行规则
猜你喜欢

leetcode-20. Valid parentheses -js version

认知篇----2022高考志愿该如何填报

微服务系统设计——API 网关服务设计

双位置继电器RXMVB2 R251 204 110DC

Tri rapide (non récursif) et tri de fusion

Edge loads web pages in IE mode - edge sets ie compatibility

竣达技术丨多品牌精密空调集中监控方案

QT using Valgrind to analyze memory leaks

Leetcode298 weekly race record

Vue学习笔记(五)Vue2页面跳转问题 | vue-router路由概念、分类与使用 | 编程式路由导航 | 路由组件的缓存 | 5种路由导航守卫 | 嵌套路由 | Vue2项目的打包与部署
随机推荐
py2neo基本语法
Almost because of json Stringify lost his bonus
网易云音乐params和encSecKey参数生成代码
高翔slam14讲-笔记1
Double position relay jdp-1440/dc110v
【FPGA】 基于FPGA分频,倍频设计实现
Vue学习笔记(五)Vue2页面跳转问题 | vue-router路由概念、分类与使用 | 编程式路由导航 | 路由组件的缓存 | 5种路由导航守卫 | 嵌套路由 | Vue2项目的打包与部署
《数据库原理与应用》第一版 马春梅……编著 期末复习笔记
【622. 设计循环队列】
Epics record reference 5 -- array analog input recordarray analog input (AAI)
重映像(STM32)
How pychart installs packages
Experience oceanbase database under win10
Opencv实现对象跟踪
Microservice system design -- unified authentication service design
Opencv implements object tracking
DAST black box vulnerability scanner part 6: operation (final)
Web3还没实现,Web5乍然惊现!
洛谷P2939 [USACO09FEB]Revamping Trails G 题解
Laptop does not have WiFi option solution