当前位置:网站首页>[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 .
边栏推荐
- Microservice system design -- API gateway service design
- Unity中跨平台获取系统音量
- Web3 has not been implemented yet, web5 suddenly appears!
- 007 basics of C language: C operator
- neo4j图数据库基本概念
- Quick sort (non recursive) and merge sort
- Two position relay xjls-8g/220
- 竣达技术丨多品牌精密空调集中监控方案
- 006 C language foundation: C storage class
- Cognition - how to fill in 2022 college entrance examination volunteers
猜你喜欢

微服务系统设计——服务注册与发现和配置设计
![[C language] keyword supplement](/img/c5/171e0d8537d9f09c688e31b290ad65.jpg)
[C language] keyword supplement

RTP sending PS stream tool (open source)

Two position relay xjls-8g/220

Double position relay jdp-1440/dc110v

Wechat applet websocket use case

微服务系统设计——服务熔断和降级设计
![[station B up dr_can learning notes] Kalman filter 1](/img/18/ee21d31f6a118e4e4ad466b55361cc.gif)
[station B up dr_can learning notes] Kalman filter 1
![Mechanical transcoding journal [17] template, STL introduction](/img/78/926db660139fda3d31cceccad7096c.png)
Mechanical transcoding journal [17] template, STL introduction

清华大学开源软件镜像站网址
随机推荐
py2neo基本语法
Epics record reference 5 -- array analog input recordarray analog input (AAI)
Microservice system design -- distributed transaction service design
Zener diode zener diode sod123 package positive and negative distinction
双位置继电器XJLS-8G/220
Mechanical transcoding journal [17] template, STL introduction
LeetCode-515. 在每个树行中找最大值
leetcode298周赛记录
Some articles about component packaging and my experience
Opencv实现对象跟踪
清华大学开源软件镜像站网址
DAST 黑盒漏洞扫描器 第六篇:运营篇(终)
019 basics of C language: C preprocessing
Luogu p2939 [usaco09feb]revamping trails G
DAST black box vulnerability scanner part 6: operation (final)
OpenCV的轮廓检测和阈值处理综合运用
Ad22 Gerber files Click to open the Gerber step interface. Official solutions to problems
009 basics of C language: C loop
AcWing 第 57 场周赛---BC题挺好
jq怎么获取倒数的元素