使用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 ...
随机推荐
- 第二章 Java程序设计环境
安装 Java 开发工具包 JDK : 编写Java程序的程序员使用的软件 JRE : 运行Java程序的环境,包含JVM和基本类库, 但不包含编译器 SE, EE, ME Java FX : 用于图 ...
- POJ 1251 Jungle Roads (最小生成树)
题目: Description The Head Elder of the tropical island of Lagrishan has a problem. A burst of foreign ...
- Django ORM中,如何使用Count来关联对象的子集数量
示例models 解决方法 有时候,我们想要获取一个对象关联关系的数量,但是我们不要所有的关联对象,我们只想要符合规则的那些关联对象的数量. 示例models # models.py from dja ...
- TCP-IP详解笔记7
TCP-IP详解笔记7 TCP: 传输控制协议(初步) 使用差错校正码来纠正通信问题, 自动重复请求(Automatic Repeat Request, ARQ). 分组重新排序, 分组复制, 分组丢 ...
- Nginx中if语句中的判断条件
一.if语句中的判断条件(nginx) 1.正则表达式匹配: ==:等值比较; ~:与指定正则表达式模式匹配时返回“真”,判断匹配与否时区分字符大小写: ~*:与指定正则表达式模式匹配时返回“真”,判 ...
- activiti工作流笔记
什么是activiti? Activiti是一个身经百战的业务流程管理引擎, 并且还是一个流程平台 为什么要用工作流引擎? 简单来说,就是为了统一管理流程业务. 想想看,如果要设计一个流程的程序,通常 ...
- IT行业中文资源网址集绵
1. IT网址:https://github.com/ityouknow/awesome-list 2.后端架构师网址:https://github.com/xingshaocheng/archite ...
- 小程序 -- ui布局
Flex布局 相对定位和绝对定位 弹性盒模型 display flex-direction flex-wrap :nowrap(不换行)/ wrap(换行,第一行在上方)/ wrap-reverse ...
- every循环
一.语法 var result = myArr.every(function(item, index){ return item>0; }) //全部满足,才为true every方法检测数组中 ...
- 如何在 code blocks中使用 mkl库
为了安装caffe, 所以安装了mkl, 现在想在codeblock的项目中使用mkl. 设置mkl环境变量: mkl安装好后默认是在/opt/intel/mkl中,其中/opt/intel/mkl/ ...