精品国产人成在线_亚洲高清无码在线观看_国产在线视频国产永久2021_国产AV综合第一页一个的一区免费影院黑人_最近中文字幕MV高清在线视频

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

Uart協議及Verilog代碼

FPGA之家 ? 來源:FPGA之家 ? 作者:FPGA之家 ? 2022-07-31 10:26 ? 次閱讀

代碼注釋有些匆忙,如有錯誤注釋還請批評,僅作參考

UART

Uart比較簡單,所以僅對tx作比較詳細的注釋,但里面一些內容還是值得新手學習的

1開始位(低電平)+8位數據+1停止位(高電平,這里選的是一個周期高電平,也可兩個)(無校驗位)

1、prescale是完成一個bit需要主時鐘計數的次數(其和主時鐘以及波特率之間的關系參考網上文章)

2、進入uart模塊的異步信號,最好使用提供的同步器同步

3、異步復位信號最好使用提供的同步器同步

4、波特率任意選,只要時鐘夠大,能夠符合誤碼率計算即可,這里使用的是125Mhz

5、基本的思想就是移位

6、傳輸條件就是握手

7、如果使用Xlinx的片子,建議使用全局時鐘資源(IBUFG后面連接BUFG的方法是最基本的全局時鐘資源的使用方法)

8、這個完整的代碼就是使用IBUFG+BUFG

9、傳輸雖然簡單,但對于新手來講,還是有挺多的知識點值得學習的點

10、公眾號只是對代碼進行了簡單注釋

UART的發送數據模塊


// 歡迎大家關注公眾號:AriesOpenFPGA// Q群:808033307// Language: Verilog 2001
// 代碼注釋有些匆忙,如有錯誤注釋還請批評,僅作參考// UART// 1開始位+8位數據+1停止位(無校驗)// prescale是完成一個bit需要主時鐘計數的次數(其和主時鐘以及波特率之間的關系參考網上文章)// 進入uart模塊的異步信號,最好使用提供的同步器同步// 異步復位信號最好使用提供的同步器同步// 波特率任意選,只要時鐘夠大,能夠符合誤碼率計算即可,這里使用的是125M// 基本的思想就是移位// 傳輸條件就是握手// 如果使用Xlinx的片子,建議使用全局時鐘資源(IBUFG后面連接BUFG的方法是最基本的全局時鐘資源的使用方法)// 這個完整的代碼就是使用IBUFG+BUFG// 傳輸雖然簡單,但對于新手來講,還是有挺多的知識點值得學習的// 公眾號只是對代碼進行了簡單注釋`timescale 1ns / 1ps/* AXI4-Stream UART */module uart_tx #(    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, // 該模塊準備好接收數據
    output wire                   txd,     // UART interface    output wire                   busy,    // Status 線忙    input  wire [15:0]            prescale // Configuration 預分度);
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;  // 從機沒有準備好發送            txd_reg           <= 1;  // 發送線拉高            prescale_reg      <= 0;  //             bit_cnt           <= 0;  // 位計數器初始化為0            busy_reg          <= 0;  // 復位后為不忙狀態        end    else         begin            if (prescale_reg > 0)                 begin                    s_axis_tready_reg <= 0;                    prescale_reg      <= prescale_reg - 1;                end             else if (bit_cnt == 0)     //比特計數器為0                begin                    s_axis_tready_reg <= 1;   // 從機把ready信號拉高                    busy_reg          <= 0;   // 忙信號拉低無效                    if (s_axis_tvalid)        // 如果從機準備好接收數據                        begin                            s_axis_tready_reg <= !s_axis_tready_reg;   //                             prescale_reg      <= (prescale << 3)-1;    //                             bit_cnt           <= DATA_WIDTH+1;         // 一共10次計數                            data_reg          <= {1'b1, s_axis_tdata}; //                             txd_reg           <= 0;                    // 起始位0(起始位tx拉低,停止位拉高)                            busy_reg          <= 1;                    // 開始傳輸后,傳輸線進入忙狀態                        end                end             else                 begin                    if (bit_cnt > 1)   //                         begin                            bit_cnt             <= bit_cnt - 1;                            prescale_reg        <= (prescale << 3)-1;  // 經過(prescale << 3)-1次的系統時鐘計數,完成一位的移位                            {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的接收模塊(不詳細講解)


// 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) // 初始化各種參數           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) // 準備有數據要發以及準被好發            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)  // 實際的read為0時,開始計數bit                            begin                                               bit_cnt <= bit_cnt - 1;                                prescale_reg <= (prescale << 3)-1;  //prescale是16位移3位減1位,因為prescale_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

同步(異步復位)模塊


// 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

同步(異步信號)模塊


// 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

審核編輯 :李倩


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • Verilog
    +關注

    關注

    28

    文章

    1333

    瀏覽量

    109721
  • uart
    +關注

    關注

    22

    文章

    1199

    瀏覽量

    100833
  • 代碼
    +關注

    關注

    30

    文章

    4671

    瀏覽量

    67771

原文標題:Uart協議及Verilog代碼

文章出處:【微信號:zhuyandz,微信公眾號:FPGA之家】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    UART串口通訊協議解析

    - 數據接受接口 GND - 保證兩設備共地,有統一的參考平面 通信協議 UART串口傳輸的數據被組織成數據包。每個數據包包含1個起始位,5至9個數據位,可選的奇偶校驗位和1或1.5或2個停止位
    發表于 09-12 16:01

    UART協議的工作原理和應用場景

    UART(Universal Asynchronous Receiver/Transmitter,通用異步收發傳輸器)協議是一種廣泛使用的串行通信協議,它允許計算機與外部設備之間通過串行接口進行數據傳輸。以下是對
    的頭像 發表于 08-25 17:15 ?1403次閱讀

    簡單認識UART通信協議

    UART(Universal Asynchronous Receiver/Transmitter,通用異步收發傳輸器)通信協議是一種常見的串行通信協議,廣泛應用于計算機、嵌入式系統、傳感器、無線通信
    的頭像 發表于 07-25 18:07 ?993次閱讀

    簡單認識UART串行通信協議

    在電子通信領域,UART(Universal Asynchronous Receiver/Transmitter,通用異步收發傳輸器)是一種非常常見的串行通信協議。它被廣泛應用于各種設備之間
    的頭像 發表于 05-27 16:09 ?1429次閱讀

    UART串口通信協議是什么?

    UART (Universal Asynchronous Receiver/Transmitter) 是一種通信接口協議,用于實現串口通信。它是一種簡單的、可靠的、廣泛應用的串口通信協議。它是由美國
    的頭像 發表于 03-19 17:26 ?964次閱讀

    verilog調用模塊端口對應方式

    Verilog中的模塊端口對應方式,并提供示例代碼和詳細解釋,以幫助讀者更好地理解和應用。 首先,我們來了解一下Verilog中的模塊和模塊端口。一個Verilog模塊被定義為包含一組
    的頭像 發表于 02-23 10:20 ?1089次閱讀

    verilog function函數的用法

    Verilog 是一種硬件描述語言 (HDL),主要用于描述數字電子電路的行為和結構。在 Verilog 中,函數 (Function) 是一種用于執行特定任務并返回一個值的可重用代碼塊。函數在
    的頭像 發表于 02-22 15:49 ?3941次閱讀

    怎么用emac實現Verilog自動連線呢?

    我們在編寫一些比較復雜的Verilog代碼時,通常需要進行大量的手動連線工作,這種工作十分容易出錯,并且在代碼模塊的嵌套層級較多時,更改里層的一個代碼
    的頭像 發表于 01-24 10:03 ?1062次閱讀

    最詳細的UART通訊協議分析在這里

    下載本篇文章的pdf版本:UART協議分析.pdf1.協議基礎1.1.協議簡介UART是“UniversalAsynchronousRece
    的頭像 發表于 01-12 14:15 ?1.4w次閱讀
    最詳細的<b class='flag-5'>UART</b>通訊<b class='flag-5'>協議</b>分析在這里

    verilog bug的利器—notepad++介紹

    相信大家寫verilog代碼的時候,都會用到notepad++,大家也知道notepad++可以和vivado關聯使用,這樣寫起工程代碼的時候,調試很方便。
    的頭像 發表于 12-21 09:41 ?1604次閱讀
    找<b class='flag-5'>verilog</b> bug的利器—notepad++介紹

    淺談Verilog HDL代碼編寫風格

    深層次的問題,對于這個行業來說可能我才是一直腳踩在門外面。所以這篇文章是寫給一些剛開始學習FPGA、Verilog HDL的同學,我看過一些大神寫的代碼,然后盡量模仿大神寫法,經過好幾個大神的影響和自己
    的頭像 發表于 11-20 10:04 ?592次閱讀
    淺談<b class='flag-5'>Verilog</b> HDL<b class='flag-5'>代碼</b>編寫風格

    UART協議是干啥的

    UART協議是電子傳輸中一種常見的信號協議,通常只需要三根信號線就可以完成數據的收發,分別是TX,RX,GND。 UART(universal asynchronous receive
    的頭像 發表于 11-06 10:08 ?1624次閱讀
    <b class='flag-5'>UART</b><b class='flag-5'>協議</b>是干啥的

    什么通信協議?UART自定義通信協議代碼實現方法

    我們學習單片機,首先接觸的可能是點燈(GPIO),再次就是串口(UART)。
    的頭像 發表于 11-02 09:03 ?1155次閱讀
    什么通信<b class='flag-5'>協議</b>?<b class='flag-5'>UART</b>自定義通信<b class='flag-5'>協議</b><b class='flag-5'>代碼</b>實現方法

    JK觸發器與T觸發器的Verilog代碼實現和RTL電路實現

    JK 觸發器的 Verilog 代碼實現和 RTL 電路實現
    的頭像 發表于 10-09 17:29 ?3752次閱讀
    JK觸發器與T觸發器的<b class='flag-5'>Verilog</b><b class='flag-5'>代碼</b>實現和RTL電路實現

    Verilog HDL實用精解配套源代碼

    輕松成為設計高手Verilog HDL 實用精解 配套源代碼。
    發表于 10-09 06:28