Uart比較簡(jiǎn)單,所以僅對(duì)tx作比較詳細(xì)的注釋,但里面一些內(nèi)容還是值得新手學(xué)習(xí)的
1開始位(低電平)+8位數(shù)據(jù)+1停止位(高電平,這里選的是一個(gè)周期高電平,也可兩個(gè))(無(wú)校驗(yàn)位)
1、prescale是完成一個(gè)bit需要主時(shí)鐘計(jì)數(shù)的次數(shù)(其和主時(shí)鐘以及波特率之間的關(guān)系參考網(wǎng)上文章)
2、進(jìn)入uart模塊的異步信號(hào),最好使用提供的同步器同步
3、異步復(fù)位信號(hào)最好使用提供的同步器同步
4、波特率任意選,只要時(shí)鐘夠大,能夠符合誤碼率計(jì)算即可,這里使用的是125Mhz
5、基本的思想就是移位
6、傳輸條件就是握手
7、如果使用Xlinx的片子,建議使用全局時(shí)鐘資源(IBUFG后面連接BUFG的方法是最基本的全局時(shí)鐘資源的使用方法)
8、這個(gè)完整的代碼就是使用IBUFG+BUFG
9、傳輸雖然簡(jiǎn)單,但對(duì)于新手來(lái)講,還是有挺多的知識(shí)點(diǎn)值得學(xué)習(xí)的點(diǎn)
10、公眾號(hào)只是對(duì)代碼進(jìn)行了簡(jiǎn)單注釋
UART的發(fā)送數(shù)據(jù)模塊
// 歡迎大家關(guān)注公眾號(hào):AriesOpenFPGA// Q群:808033307// Language: Verilog 2001 // 代碼注釋有些匆忙,如有錯(cuò)誤注釋還請(qǐng)批評(píng),僅作參考// UART// 1開始位+8位數(shù)據(jù)+1停止位(無(wú)校驗(yàn))// prescale是完成一個(gè)bit需要主時(shí)鐘計(jì)數(shù)的次數(shù)(其和主時(shí)鐘以及波特率之間的關(guān)系參考網(wǎng)上文章)// 進(jìn)入uart模塊的異步信號(hào),最好使用提供的同步器同步// 異步復(fù)位信號(hào)最好使用提供的同步器同步// 波特率任意選,只要時(shí)鐘夠大,能夠符合誤碼率計(jì)算即可,這里使用的是125M// 基本的思想就是移位// 傳輸條件就是握手// 如果使用Xlinx的片子,建議使用全局時(shí)鐘資源(IBUFG后面連接BUFG的方法是最基本的全局時(shí)鐘資源的使用方法)// 這個(gè)完整的代碼就是使用IBUFG+BUFG// 傳輸雖然簡(jiǎn)單,但對(duì)于新手來(lái)講,還是有挺多的知識(shí)點(diǎn)值得學(xué)習(xí)的// 公眾號(hào)只是對(duì)代碼進(jìn)行了簡(jiǎn)單注釋`timescale 1ns / 1ps/* AXI4-Stream UART */module uart_tx #( parameter DATA_WIDTH = 8)( input wire clk, // 系統(tǒng)時(shí)鐘 input wire rst, // 復(fù)位信號(hào) /* AXI input */ input wire [DATA_WIDTH-1:0] s_axis_tdata, // 輸入到這個(gè)模塊準(zhǔn)備發(fā)送出去的數(shù)據(jù) input wire s_axis_tvalid, // 有數(shù)據(jù)要輸入到這個(gè)模塊 output wire s_axis_tready, // 該模塊準(zhǔn)備好接收數(shù)據(jù) output wire txd, // UART interface output wire busy, // Status 線忙 input wire [15:0] prescale // Configuration 預(yù)分度); reg s_axis_tready_reg = 0;reg txd_reg = 1;reg busy_reg = 0; reg [DATA_WIDTH:0] data_reg = 0;reg [18:0] prescale_reg = 0;reg [3:0] bit_cnt = 0; assign s_axis_tready = s_axis_tready_reg;assign txd = txd_reg;assign busy = busy_reg; always @(posedge clk) begin if (rst) begin s_axis_tready_reg <= 0; // 從機(jī)沒有準(zhǔn)備好發(fā)送 txd_reg <= 1; // 發(fā)送線拉高 prescale_reg <= 0; // bit_cnt <= 0; // 位計(jì)數(shù)器初始化為0 busy_reg <= 0; // 復(fù)位后為不忙狀態(tài) end else begin if (prescale_reg > 0) begin s_axis_tready_reg <= 0; prescale_reg <= prescale_reg - 1; end else if (bit_cnt == 0) //比特計(jì)數(shù)器為0 begin s_axis_tready_reg <= 1; // 從機(jī)把ready信號(hào)拉高 busy_reg <= 0; // 忙信號(hào)拉低無(wú)效 if (s_axis_tvalid) // 如果從機(jī)準(zhǔn)備好接收數(shù)據(jù) begin s_axis_tready_reg <= !s_axis_tready_reg; // prescale_reg <= (prescale << 3)-1; // bit_cnt <= DATA_WIDTH+1; // 一共10次計(jì)數(shù) data_reg <= {1'b1, s_axis_tdata}; // txd_reg <= 0; // 起始位0(起始位tx拉低,停止位拉高) busy_reg <= 1; // 開始傳輸后,傳輸線進(jìn)入忙狀態(tài) end end else begin if (bit_cnt > 1) // begin bit_cnt <= bit_cnt - 1; prescale_reg <= (prescale << 3)-1; // 經(jīng)過(guò)(prescale << 3)-1次的系統(tǒng)時(shí)鐘計(jì)數(shù),完成一位的移位 {data_reg, txd_reg} <= {1'b0, data_reg}; // 移位操作 end else if (bit_cnt == 1) begin bit_cnt <= bit_cnt - 1; prescale_reg <= (prescale << 3); txd_reg <= 1; // 停止位1 end end end end endmodule
UART的接收模塊(不詳細(xì)講解)
// Language: Verilog 2001 `timescale 1ns / 1ps /* * AXI4-Stream UART */module uart_rx #( parameter DATA_WIDTH = 8)( input wire clk, input wire rst, /* AXI output */ output wire [DATA_WIDTH-1:0] m_axis_tdata, output wire m_axis_tvalid, input wire m_axis_tready, /* UART interface */ input wire rxd, /* Status */ output wire busy, output wire overrun_error, output wire frame_error, /* Configuration */ input wire [15:0] prescale ); reg [DATA_WIDTH-1:0] m_axis_tdata_reg = 0;reg m_axis_tvalid_reg = 0; reg rxd_reg = 1; reg busy_reg = 0;reg overrun_error_reg = 0;reg frame_error_reg = 0; reg [DATA_WIDTH-1:0] data_reg = 0;reg [18:0] prescale_reg = 0;reg [3:0] bit_cnt = 0; assign m_axis_tdata = m_axis_tdata_reg;assign m_axis_tvalid = m_axis_tvalid_reg; assign busy = busy_reg;assign overrun_error = overrun_error_reg;assign frame_error = frame_error_reg; always @(posedge clk) begin if (rst) // 初始化各種參數(shù) begin m_axis_tdata_reg <= 0; m_axis_tvalid_reg <= 0; rxd_reg <= 1; prescale_reg <= 0; bit_cnt <= 0; busy_reg <= 0; overrun_error_reg <= 0; frame_error_reg <= 0; end else begin rxd_reg <= rxd; overrun_error_reg <= 0; frame_error_reg <= 0; if (m_axis_tvalid && m_axis_tready) // 準(zhǔn)備有數(shù)據(jù)要發(fā)以及準(zhǔn)被好發(fā) begin m_axis_tvalid_reg <= 0; end if (prescale_reg > 0) // begin prescale_reg <= prescale_reg - 1; end else if (bit_cnt > 0) begin if (bit_cnt > DATA_WIDTH+1) begin if (!rxd_reg) // 實(shí)際的read為0時(shí),開始計(jì)數(shù)bit begin bit_cnt <= bit_cnt - 1; prescale_reg <= (prescale << 3)-1; //prescale是16位移3位減1位,因?yàn)閜rescale_reg end else begin bit_cnt <= 0; prescale_reg <= 0; end end else if (bit_cnt > 1) begin bit_cnt <= bit_cnt - 1; prescale_reg <= (prescale << 3)-1; data_reg <= {rxd_reg, data_reg[DATA_WIDTH-1:1]}; end else if (bit_cnt == 1) begin bit_cnt <= bit_cnt - 1; if (rxd_reg) begin m_axis_tdata_reg <= data_reg; m_axis_tvalid_reg <= 1; overrun_error_reg <= m_axis_tvalid_reg; end else begin frame_error_reg <= 1; end end end else begin busy_reg <= 0; if (!rxd_reg) begin prescale_reg <= (prescale << 2)-2; bit_cnt <= DATA_WIDTH + 2; data_reg <= 0; busy_reg <= 1; end end endendendmodule
UART頂層
// Language: Verilog 2001 `timescale 1ns / 1ps /* * AXI4-Stream UART */module uart #( parameter DATA_WIDTH = 8)( input wire clk, input wire rst, /* * AXI input */ input wire [DATA_WIDTH-1:0] s_axis_tdata, input wire s_axis_tvalid, output wire s_axis_tready, /* * AXI output */ output wire [DATA_WIDTH-1:0] m_axis_tdata, output wire m_axis_tvalid, input wire m_axis_tready, /* * UART interface */ input wire rxd, output wire txd, /* * Status */ output wire tx_busy, output wire rx_busy, output wire rx_overrun_error, output wire rx_frame_error, /* * Configuration */ input wire [15:0] prescale ); uart_tx #( .DATA_WIDTH(DATA_WIDTH))uart_tx_inst ( .clk(clk), .rst(rst), // axi input .s_axis_tdata(s_axis_tdata), .s_axis_tvalid(s_axis_tvalid), .s_axis_tready(s_axis_tready), // output .txd(txd), // status .busy(tx_busy), // configuration .prescale(prescale)); uart_rx #( .DATA_WIDTH(DATA_WIDTH))uart_rx_inst ( .clk(clk), .rst(rst), // axi output .m_axis_tdata(m_axis_tdata), .m_axis_tvalid(m_axis_tvalid), .m_axis_tready(m_axis_tready), // input .rxd(rxd), // status .busy(rx_busy), .overrun_error(rx_overrun_error), .frame_error(rx_frame_error), // configuration .prescale(prescale)); endmodule
同步(異步復(fù)位)模塊
// Language: Verilog-2001// 很常用的模塊`timescale 1 ns / 1 ps /* * Synchronizes an active-high asynchronous reset signal to a given clock by * using a pipeline of N registers. */module sync_reset #( parameter N=2 // depth of synchronizer)( input wire clk, input wire rst, output wire sync_reset_out); reg [N-1:0] sync_reg = {N{1'b1}}; assign sync_reset_out = sync_reg[N-1]; always @(posedge clk or posedge rst) begin if (rst) sync_reg <= {N{1'b1}}; else sync_reg <= {sync_reg[N-2:0], 1'b0};end endmodule
同步(異步信號(hào))模塊
// Language: Verilog-2001//很常用的模塊`timescale 1 ns / 1 ps /* * Synchronizes an asyncronous signal to a given clock by using a pipeline of * two registers. */module sync_signal #( parameter WIDTH=1, // width of the input and output signals parameter N=2 // depth of synchronizer)( input wire clk, input wire [WIDTH-1:0] in, output wire [WIDTH-1:0] out); reg [WIDTH-1:0] sync_reg[N-1:0]; /* * The synchronized output is the last register in the pipeline. */assign out = sync_reg[N-1]; integer k; always @(posedge clk) begin sync_reg[0] <= in; for (k = 1; k < N; k = k + 1) begin sync_reg[k] <= sync_reg[k-1]; endend endmodule
原文標(biāo)題:Uart協(xié)議及Verilog代碼
文章出處:【微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
接收模塊
+關(guān)注
關(guān)注
1文章
22瀏覽量
10584 -
uart
+關(guān)注
關(guān)注
22文章
1249瀏覽量
102525 -
同步器
+關(guān)注
關(guān)注
1文章
101瀏覽量
14916 -
數(shù)據(jù)模塊
+關(guān)注
關(guān)注
0文章
11瀏覽量
9819
原文標(biāo)題:Uart協(xié)議及Verilog代碼
文章出處:【微信號(hào):zhuyandz,微信公眾號(hào):FPGA之家】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
關(guān)于uart模塊的問(wèn)題
UART從模塊接收到的數(shù)據(jù)無(wú)法顯示
如何使用Assembly和pic16f877從兩個(gè)發(fā)送器接收UART數(shù)據(jù)
怎么用UART發(fā)送和接收數(shù)據(jù)?
Verilog實(shí)現(xiàn)UART之二:發(fā)送模塊

UART串口WiFi模塊的工作原理及應(yīng)用

UART的基本協(xié)議與設(shè)計(jì)實(shí)例模塊劃分以及整體實(shí)現(xiàn)概述

Android藍(lán)牙編程如何發(fā)送和接收16進(jìn)制數(shù)據(jù)

UART的發(fā)送數(shù)據(jù)模塊及Verilog代碼
STC15F104W 使用 315/433 MHz 超再生模塊發(fā)送/接收數(shù)據(jù)

K025 基于51 315(或者433)發(fā)送和接收模塊測(cè)試

使用STM32的射頻模塊以無(wú)線方式發(fā)送和接收數(shù)據(jù)

如何根據(jù)UART傳輸協(xié)議將數(shù)據(jù)發(fā)送出去呢?

評(píng)論