使用Xilinx UART-LITE IP实现串口--逻辑代码实现
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2019/01/10 21:13:43
// Design Name:
// Module Name: uart_top
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
////////////////////////////////////////////////////////////////////////////////// module uart_top(
input CLK100MHZ,
input ck_rst,
output tx,
input rx,
output led
); localparam COUNT_5MS = 'h2_FA_F0_7F;//100M 500ms
//闪灯指示
reg [:]r_count = 'h0;
reg r_led = 'b0;
always @ (posedge CLK100MHZ)
begin
if(r_count >= COUNT_5MS) begin
r_count <= 'h0;
r_led <= ~r_led;
end
else begin
r_count <= r_count +'b1;
r_led <= r_led;
end
end
assign led = r_led; wire w_uart_rstn;
(*MARK_DEBUG = "TRUE"*)wire w_uart_int;
(*MARK_DEBUG = "TRUE"*)reg [:]s_axi_awaddr;
(*MARK_DEBUG = "TRUE"*)reg s_axi_awvalid;
(*MARK_DEBUG = "TRUE"*)wire s_axi_awready;
(*MARK_DEBUG = "TRUE"*)reg [:]s_axi_wdata;
(*MARK_DEBUG = "TRUE"*)reg [:]s_axi_wstrb;
(*MARK_DEBUG = "TRUE"*)reg s_axi_wvalid = 'b0;
(*MARK_DEBUG = "TRUE"*)wire s_axi_wready;
(*MARK_DEBUG = "TRUE"*)wire [:]s_axi_bresp;
(*MARK_DEBUG = "TRUE"*)wire s_axi_bvalid;
(*MARK_DEBUG = "TRUE"*)reg s_axi_bready = 'b0;
(*MARK_DEBUG = "TRUE"*)reg [:]s_axi_araddr = 'h0;
(*MARK_DEBUG = "TRUE"*)reg s_axi_arvalid = 'b0;
(*MARK_DEBUG = "TRUE"*)wire s_axi_arready;//Read ready. This signal indicates that the master can accept the read data and response information.
(*MARK_DEBUG = "TRUE"*)wire [:]s_axi_rdata;
(*MARK_DEBUG = "TRUE"*)wire [:]s_axi_rresp;
wire s_axi_rvalid;
(*MARK_DEBUG = "TRUE"*)reg s_axi_rready = 'b0;
axi_uartlite_0 uart_lite
(
.s_axi_aclk(CLK100MHZ),
.s_axi_aresetn(ck_rst), .interrupt(w_uart_int),
.s_axi_awaddr(s_axi_awaddr),// : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
.s_axi_awvalid(s_axi_awvalid),// : IN STD_LOGIC;
.s_axi_awready(s_axi_awready),// : OUT STD_LOGIC;
.s_axi_wdata(s_axi_wdata),// : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
.s_axi_wstrb(s_axi_wstrb),// : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
.s_axi_wvalid(s_axi_wvalid),// : IN STD_LOGIC;
.s_axi_wready(s_axi_wready),// : OUT STD_LOGIC;
.s_axi_bresp(s_axi_bresp),// : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
.s_axi_bvalid(s_axi_bvalid),// : OUT STD_LOGIC;
.s_axi_bready(s_axi_bready),// : IN STD_LOGIC;
.s_axi_araddr(s_axi_araddr),// : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
.s_axi_arvalid(s_axi_arvalid),//: IN STD_LOGIC;
.s_axi_arready(s_axi_arready),//: OUT STD_LOGIC;
.s_axi_rdata(s_axi_rdata),// : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
.s_axi_rresp(s_axi_rresp),// : OUT STD_LOGIC_VECTOR(1 DOWNTO 0);
.s_axi_rvalid(s_axi_rvalid),// : OUT STD_LOGIC;
.s_axi_rready(s_axi_rready),// : IN STD_LOGIC; .rx(rx),// : IN STD_LOGIC;
.tx(tx)// : OUT STD_LOGIC
);
//debug
wire begin_init;
reg [:]r_receive_data;
vio_0 debug(
.clk(CLK100MHZ),
.probe_in0(r_receive_data),
.probe_out0(begin_init)
);
//receive data to fifo
(*MARK_DEBUG = "TRUE"*)wire [:] data_count;//8 bit count
(*MARK_DEBUG = "TRUE"*)wire [:]w_receive_data;
wire fifo_empty;
fifo_generator_0 receive_fifo
(
.clk(CLK100MHZ),// : IN STD_LOGIC;
.srst(~ck_rst),// : IN STD_LOGIC;
.din(s_axi_rdata[:]),// : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
.wr_en(s_axi_rvalid & (state == 'b00000100)),// : IN STD_LOGIC;
.rd_en(r_Read_en),// : IN STD_LOGIC;
.dout(w_receive_data),// : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
.full(),// : OUT STD_LOGIC;
.almost_full(),// : OUT STD_LOGIC;
.empty(fifo_empty),// : OUT STD_LOGIC;
.almost_empty(),// : OUT STD_LOGIC;
.data_count(data_count)// : OUT STD_LOGIC_VECTOR(9 DOWNTO 0)
); parameter IDLE = 'b00000001;
parameter INIT = 'b00000010;
parameter RECIVE = 'b00000100;
parameter T_R_IDLE = 'b00001000;
parameter RECEIVE = 'b00010000;
parameter CHECK_STA = 'b00100000;
parameter state7 = 'b01000000;
parameter state8 = 'b10000000; (*MARK_DEBUG = "TRUE"*)reg [:] state = IDLE;
(*MARK_DEBUG = "TRUE"*)reg [:]cnt = 'h00; always @(posedge CLK100MHZ)
if (~ck_rst) begin
state <= IDLE;
end
else
case (state)
IDLE : begin
if (begin_init)
state <= INIT;
else if (w_uart_int)
state <= RECIVE;
else
state <= IDLE;
end
INIT : begin//向0xC写入0x1F,使能中断,清空W/R FIFO
if (s_axi_bvalid && (s_axi_bresp == 'b00))
state <= CHECK_STA;
else
state <= INIT;
end
RECIVE : begin
if (s_axi_rvalid) begin
state <= CHECK_STA;
r_receive_data <= s_axi_rdata;
end
else begin
state <= RECIVE;
r_receive_data <= r_receive_data;
end
end CHECK_STA : begin//检查状态寄存器
if (s_axi_rvalid & s_axi_rdata[])//receive buf is not empt
state <= RECIVE;
else
state <= CHECK_STA;
end
default:begin end
endcase reg [:]r_state;
always @ (posedge CLK100MHZ)
r_state <= state; always @ (posedge CLK100MHZ) begin
if(~ck_rst) begin
cnt <= 'h00;
end
else begin
case(state)
RECIVE :begin
if(s_axi_rvalid | (cnt>'h4))
cnt <= 'h00;
else
cnt <= cnt +'b1;
end
CHECK_STA :begin
if((s_axi_rvalid & s_axi_rdata[]) | (cnt>'h4))
cnt <= 'h00;
else
cnt <= cnt +'b1;
end
default:begin
cnt <= 'h00;
end
endcase end
end always @ (posedge CLK100MHZ)
begin
case(state)
IDLE:begin
s_axi_awaddr <='h0;
s_axi_wdata <= 'h00_00_00_00;
s_axi_wstrb <= 'h0;
s_axi_arvalid <= 'b0;
if(begin_init) begin
s_axi_awvalid <= 'b1;
s_axi_wvalid <= 'b1;
end
else begin
s_axi_awvalid <= 'b0;
s_axi_wvalid <= 'b0;
end
end
INIT:begin
if(s_axi_wready) begin
s_axi_bready <= 'b1;
s_axi_awvalid <= 'b0;
s_axi_wvalid <= 'b0;
end
else begin
s_axi_bready <= 'b0; s_axi_awaddr <='hc;
s_axi_awvalid <= s_axi_awvalid;
s_axi_wdata <= 'h1f;
s_axi_wstrb <= 'hf;
s_axi_wvalid <= s_axi_wvalid;
end
end
RECIVE:begin
if(cnt > 'h3) begin
s_axi_arvalid <= 'b0;
end
else if(cnt > 'h2) begin
s_axi_arvalid <= 'b1;
end
else if(cnt > 'h1) begin
s_axi_araddr <='h0;
s_axi_rready <= 'b1;
end
else begin
s_axi_rready <= 'b1;
end
end
CHECK_STA:begin
if(cnt > 'h3) begin
s_axi_arvalid <= 'b0;
end
else if(cnt > 'h2) begin
s_axi_arvalid <= 'b1;
end
else if(cnt > 'h1) begin
s_axi_araddr <='h8;
s_axi_rready <= 'b1;
end
else begin
s_axi_rready <= 'b1;
end
end
default:begin
s_axi_awaddr <='h0;
s_axi_awvalid <= 'b0;
s_axi_wdata <= 'h00_00_00_00;
s_axi_wstrb <= 'h0;
s_axi_wvalid <= 'b0; s_axi_arvalid <= 'b0;
end
endcase
end
//read FIFO,unpack
//如果读到2F,开始计数,再读11个字节,并相加,若和的最后一个字节为00,这是一个完整包,否则丢掉重新找2F parameter IDLE_P = 'b0001;
parameter FIRST_BYTE = 'b0010;
parameter RECEIVE_PACK = 'b0100;
parameter CHECK_PACK = 'b1000; (*MARK_DEBUG = "TRUE"*)reg [:] state_pack = IDLE_P;
(*MARK_DEBUG = "TRUE"*)reg [:] r_Byte_cnt = 'h0;
always @(posedge CLK100MHZ)
if (~ck_rst) begin
state_pack <= IDLE_P;
end
else
case (state_pack)
IDLE_P : begin
if (r_Read_en)
state_pack <= FIRST_BYTE;
else
state_pack <= IDLE_P;
end
FIRST_BYTE : begin
if (w_receive_data == 'h2f)//check pack header
state_pack <= RECEIVE_PACK;
else
state_pack <= IDLE_P;;
end
RECEIVE_PACK : begin
if (r_Byte_cnt == 'hb)//
state_pack <= CHECK_PACK;
else
state_pack <= RECEIVE_PACK;
end
CHECK_PACK : begin
if (pack_check_done)//no matter success or failed
state_pack <= IDLE_P;
else
state_pack <= CHECK_PACK;
end
default : begin // Fault Recovery
state_pack <= IDLE_P;
end
endcase reg r_Read_en = 'b0;
reg [:]buf_data[:];
reg pack_check_done = 'b0;
(*MARK_DEBUG = "TRUE"*)reg check_success = 'b0;
always @ (posedge CLK100MHZ) begin
if(~ck_rst) begin
r_Read_en <= 'b0;
r_Byte_cnt <= 'h0;
pack_check_done <= 'b0;
check_success <= 'b0;
end
else begin
case(state_pack)
IDLE_P:begin
check_success <= 'b0;
r_Byte_cnt <= 'h0;
pack_check_done <= 'b0;
if(rr_fifo_empty & (~fifo_empty)) begin
r_Read_en <= 'b1;
end
else begin
r_Read_en <= 'b0;
end
end
FIRST_BYTE:begin//do nothing
r_Read_en <= 'b0;
end
RECEIVE_PACK:begin
if(rr_fifo_empty & (~fifo_empty))begin
r_Byte_cnt <= r_Byte_cnt + 'b1;
r_Read_en <= 'b1;
end
else begin
r_Byte_cnt <= r_Byte_cnt;
r_Read_en <= 'b0;
end
end
CHECK_PACK:begin
pack_check_done <= 'b1;
if(data_check[:] == 'h00) begin
check_success <= 'b1;
end
else begin
check_success <= 'b0;
end
end
default:begin end
endcase
end
end reg rr_fifo_empty;
reg rr_Read_en;
always @ (posedge CLK100MHZ) begin
rr_fifo_empty <= fifo_empty;
rr_Read_en <= r_Read_en;
end //data check and buff
(*MARK_DEBUG = "TRUE"*)reg [:]data_check = 'h0000002f;
always @ (posedge CLK100MHZ) begin
if(state_pack == IDLE_P) begin
data_check <= 'h0000002f;
end
else if((state_pack > FIRST_BYTE) & (rr_Read_en)) begin
buf_data[r_Byte_cnt] <= w_receive_data;
data_check <= data_check+w_receive_data;
end
else begin
data_check <= data_check;
end
end (*MARK_DEBUG = "TRUE"*)reg [:]r_checded_data[:];
always @ (posedge CLK100MHZ) begin
if(check_success) begin
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
r_checded_data[] <= buf_data[];
end
else begin
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
r_checded_data[] <= r_checded_data[];
end
end
endmodule
参考手册“axi_lite_ipif_ds765”及“AXI UART Lite v2.0 pg142”
AXI-LITE接口,完全按照手册上的时序才能实现!!
有陀螺数据包解包校验代码,包格式说明如下图,包校验通过才更新缓存寄存器,保证缓存寄存器内存储的数据是最新的正确数据包。
需注意,IP使用主时钟100MHz产生波特率,100M时钟并不能产生较准确的波特率,波特率较高时出现异常,后改用14.7456M晶振,5倍频后作为UART IP的输入时钟,通信正常。

使用Xilinx UART-LITE IP实现串口--逻辑代码实现的更多相关文章
- 关于Xilinx AXI Lite 源代码分析---自建带AXI接口的IP
关于Xilinx AXI Lite 源代码分析---自建带AXI接口的IP 首先需要注意此处寄存器数量的配置,它决定了slv_reg的个数. 读写数据,即是对寄存器slv_reg进行操作: 关于AXI ...
- [ZigBee] 8、ZigBee之UART剖析·二(串口收发)
前言:上一节讲UART基本知识介绍完了,并深入剖析了一个串口发送工程,本节将进一步介绍串口收发! 1.初始化 在串口初始化部分,和上一节不同的地方是: 51 U0CSR |= 0x40; //允许接收 ...
- xilinx AXI相关IP核学习
xilinx AXI相关IP核学习 1.阅读PG044 (1)AXI4‐Stream to Video Out Top‐Level Signaling Interface (2)AXI4‐Stream ...
- Linux下读写UART串口的代码
Linux下读写UART串口的代码,从IBM Developer network上拿来的东西,操作比較的复杂,就直接跳过了,好在代码能用,记录一下- 两个实用的函数- //////////////// ...
- JSBinding+Bridge.Net:框架代码与逻辑代码的关系
在JSB+Bridge工程中你可以同时维护Cs版本和Js版本的游戏. 框架代码:简称framework,表示那些不进行热更的代码.注意,这包括你自己写的代码,也包括引用的Dll,比如UnityEngi ...
- 事务并发处理: DB+ORM+逻辑代码
在学习了马士兵有关事务并发处理的视频后, 感觉对事务并发处理的概念,问题以及解决方式有了一定的了解,赶紧记录下来以备后用. 1. 事务:一系列操作要么都完成,要么一个都不完成 2. 事务并发:多个事务 ...
- 通过ASP禁止指定IP和只允许指定IP访问网站的代码
过ASP禁止指定IP和只允许指定IP访问网站的代码,需要的朋友可以参考下. 一.禁止指定IP防问网站,并执行相应操作: 代码如下: <% Dim IP,IPString,VisitIP '设置I ...
- PHP通过IP 获取 地理位置(实例代码)
发布:JB02 来源:脚本学堂 分享一例php代码,实现通过IP地址获取访问者的地理位置,在php编程中经常用到,有需要的朋友参考下吧.本节内容:PHP通过IP获取地理位置 例子: 复制代码代码示 ...
- JSBinding+Bridge:逻辑代码中操作二进制数据
以这2个函数为例 class File { public static byte[] ReadAllBytes(string path); public static void WriteAllByt ...
随机推荐
- Python3:关于列表的操作(合并、拼接,嵌套排序··)
一:# 将2个列表合并成字典,按最少个数key=['winnie','anna','lisa']value=[18,20,22] k_v=dict(zip(key,value))print(k_v) ...
- CentOS7离线安装MySQL
1.删除原有的mariadb,不然mysql装不进去 mariadb-libs-5.5.52-1.el7.x86_64 rpm -qa|grep mariadb rpm -e --nodeps mar ...
- TestNg和spring3测试报错:Failed to read candidate component class-遁地龙卷风
java.lang.IllegalStateException:Failed to load ApplicationContext Caused by: org.springframework.bea ...
- 第三章Android移植平台工具介绍
第三章Android移植平台工具介绍 进行 Android 移植的学习并不一定需要一款 Android 手机,但必须要有一款主流的开发板,开发板是用来进行嵌入式系统开发的电路板,包括中央处理器.存储器 ...
- Oracle 表操作
表操作 复制表结构和数据 CREATE TABLE table_name AS SELECT * FROM old_table_name; 复制表结构 CREATE TABLE table_name ...
- LeetCode第十二题-将数字转化为罗马数字
Integer to Roman 问题简介:将输入的int类型数字转化为罗马数字 问题详解:罗马数字由七个不同的符号表示:I,V,X,L,C,D和M 符号-数值 I - 1 V - 5 X -10 L ...
- Easyui datalist 使用记录
仅简单记录下,资料相对比较少 官方给了一个很简单的例子,没啥用处,文档:http://www.jeasyui.com/documentation/datalist.php 学习要点: 1.追加行 $( ...
- java.lang.NoClassDefFoundError: org/apache/commons/lang3/StringUtils
♦ 问题所在:项目lib包里少一个jar包 ♦ 解决办法: commons-lang3-3.1.jar 导入到项目就ok
- java 运算符的了解和运算符的优先级
Java 语言支持如下运算符: 算术运算符: +,-,*,/,%,++,-- 赋值运算符 = 扩展赋值运算符:+=,-=,*=,/= 关系运算符: >,<,>=,<=,==,! ...
- Google Android SDK开发范例大全笔记 二
网络设备管理相关相关 代码地址 1 WifiManager LocationManager分别控制 wifi及GPS WifiManager 判断网络状态 ,LocationManager判断定位状态 ...