国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

【FPGA】UART串口通信---基于FIFO

這篇具有很好參考價值的文章主要介紹了【FPGA】UART串口通信---基于FIFO。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

前言

我們在上一章完成了UART串口通信的收發(fā)模塊,這一章我們將FIFO引入進(jìn)來,使用FIFO進(jìn)行緩存數(shù)據(jù),來連接串口通信的收發(fā)模塊

一丶FIFO介紹

1.什么是FIFO?

FIFO即First In First Out,是一種先進(jìn)先出數(shù)據(jù)存儲、緩沖器,我們知道一般的存儲器是用外部的讀寫地址來進(jìn)行讀寫,而FIFO這種存儲器的結(jié)構(gòu)并不需要外部的讀寫地址而是通過自動的加一操作來控制讀寫,這也就決定了FIFO只能順序的讀寫數(shù)據(jù)

2.FIFO分類

同步FIFO
讀和寫應(yīng)用同一個時鐘。它的作用一般是做交互數(shù)據(jù)的一個緩沖,也就是說它的主要作用就是一個buffer1。

異步FIFO
讀寫應(yīng)用不同的時鐘,它有兩個主要的作用,一個是實現(xiàn)數(shù)據(jù)在不同時鐘域進(jìn)行傳遞,另一個作用就是實現(xiàn)不同數(shù)據(jù)寬度的數(shù)據(jù)接口。

3.FIFO主要參數(shù)

同步FIFO和異步FIFO略有不同,下面的參數(shù)適用于兩者。

寬度,用參數(shù)FIFO_data_size表示,也就是FIFO存儲的數(shù)據(jù)寬度;
深度,用參數(shù)FIFO_addr_size表示,也就是地址的大小,也就是說能存儲多少個數(shù)據(jù);
滿標(biāo)志,full,當(dāng)FIFO中的數(shù)據(jù)滿了以后將不再能進(jìn)行數(shù)據(jù)的寫入;
空標(biāo)志,empty,當(dāng)FIFO為空的時候?qū)⒉荒苓M(jìn)行數(shù)據(jù)的讀出;
寫地址,w_addr,由自動加一生成,將數(shù)據(jù)寫入該地址;
讀地址,r_addr,由自動加一生成,將該地址上的數(shù)據(jù)讀出;

同步FIFO和異步FIFO的最主要的不同就體現(xiàn)在空滿標(biāo)志產(chǎn)生的方式上,由此引出兩者一些不同的參數(shù)。
同步FIFO

  • 時鐘,clk,rst,讀寫應(yīng)用同一個時鐘;
  • 計數(shù)器,count,用計數(shù)器來進(jìn)行空滿標(biāo)志的判斷;

異步FIFO

  • 時鐘,clk_w,rst_w,clk_r,rst_r,讀寫應(yīng)用不同的時鐘;
  • 指針,w_pointer_gray,r_pointer_gray,用指針來判斷空滿標(biāo)識;
  • 同步指針,w_pointer_gray_sync,r_pointer_gray_sync,指針的同步操作,用來做對比產(chǎn)生空滿標(biāo)志符;

4.測試

首先配置IP核

【FPGA】UART串口通信---基于FIFO
設(shè)置路徑,我們一般會在工程目錄下創(chuàng)建一個文件夾 ip 用來存放IP核文件

【FPGA】UART串口通信---基于FIFO
【FPGA】UART串口通信---基于FIFO配置參數(shù)
【FPGA】UART串口通信---基于FIFO【FPGA】UART串口通信---基于FIFO
正常模式與前顯模式:
【FPGA】UART串口通信---基于FIFO

區(qū)別:正常模式,輸出數(shù)據(jù)與讀請求信號差一個時鐘周期;前顯模式,將數(shù)據(jù)放于數(shù)據(jù)線上,在讀請求信號拉高時,在下一個時鐘周期,輸出FIFO中的第二個數(shù)據(jù)。

【FPGA】UART串口通信---基于FIFO

【FPGA】UART串口通信---基于FIFO

【FPGA】UART串口通信---基于FIFO
最后這樣就成功引入FIFO了
【FPGA】UART串口通信---基于FIFO

5.仿真

調(diào)用ip核

module control (
    input   	        clk     ,
    input       	    rst_n   ,
    input	[7:0]       data    ,
    input   	        rdreq   ,
    input           	wrreq   ,
    output         	    empty   ,
    output       	    full    ,
    output	[7:0]       q       ,
    output	[7:0]       usedw
);
fifo	fifo_inst (
	.aclr        ( ~rst_n    ),     //復(fù)位信號取反
	.clock       ( clk       ),     //系統(tǒng)時鐘  
	.data        ( data      ),     //寫入數(shù)據(jù)     
	.rdreq       ( rdreq     ),     //讀使能
	.wrreq       ( wrreq     ),     //寫使能
	.empty       ( empty     ),     //fifo為空信號
	.full        ( full      ),     //fifo存滿信號
	.q           ( q         ),     //讀出數(shù)據(jù)
	.usedw       ( usedw     )      //可用數(shù)據(jù)量
	);

endmodule //control

testbench編寫

`timescale 1ns/1ps
module tb_control ();
reg            clk      ; 
reg            rst_n    ; 
reg  [7:0]     data     ; 
reg            rdreq    ; 
reg            wrreq    ; 
wire           empty    ; 
wire           full     ; 
wire [7:0]     q        ; 
wire [7:0]     usedw    ; 

control control(
    .clk            (clk    )  ,
    .rst_n          (rst_n  )  ,
    .data           (data   )  ,
    .rdreq          (rdreq  )  ,
    .wrreq          (wrreq  )  ,
    .empty          (empty  )  ,
    .full           (full   )  ,
    .q              (q      )  ,
    .usedw          (usedw  )
);

parameter CYCLE = 20;
always #(CYCLE/2) clk=~clk;
integer i=0,j=0;

initial begin
    clk=1;
    rst_n=1;
    data=0;
    #200.1;
    rst_n=0;   //復(fù)位
    rdreq=0;
    wrreq=0;
    #(CYCLE*10);
    rst_n=1;
    #(CYCLE*10)
   //wrreq  50M
    for(i=0;i<256;i=i+1)begin     //因為我們的數(shù)據(jù)深度設(shè)置的是256,所以這里寫進(jìn)去256個數(shù)據(jù)
        wrreq = 1'b1;//寫使能
        data = {$random};
        #CYCLE;
    end
    wrreq = 1'b0;//寫完拉低
    #(CYCLE*5);

    //rdreq  50M
    for(j=0;j<256;j=j+1)begin
        rdreq = 1'b1;//讀使能
        #CYCLE;
    end
    rdreq = 1'b0;
    #(CYCLE*10);
    

    $stop;
end

endmodule //tb_control

寫數(shù)據(jù):
【FPGA】UART串口通信---基于FIFO

讀數(shù)據(jù):

【FPGA】UART串口通信---基于FIFO

二丶UART引入FIFO

思路
首先我們將整個項目分為4個模塊

uart_rx:接收模塊- - -從上位機接收數(shù)據(jù),然后將數(shù)據(jù)發(fā)送給control模塊
uart_tx:發(fā)送模塊- - -從control模塊接收數(shù)據(jù),然后發(fā)送給上位機
control:FIFO緩存模塊- - -緩存uart_rx接收的數(shù)據(jù)并輸出給uart_tx
top: 頂層模塊

1.模塊原理圖

【FPGA】UART串口通信---基于FIFO
其中發(fā)送模塊uart_tx增加了一個ready輸出信號,因為發(fā)送模塊每434個周期發(fā)送一位數(shù)據(jù),為了防止FIFO不停的輸出數(shù)據(jù)給發(fā)送模塊,使用ready信號控制FIFO輸出數(shù)據(jù)

2.代碼設(shè)計

由于只改動了發(fā)送模塊和新增了control模塊,這里只展示這兩部分,源碼見文章末尾

control:

module control (
    input   	        clk        ,
    input       	    rst_n      ,

    input	[7:0]       dout       ,
    input               dout_vld   ,

    input               ready      , 

    output  [7:0]       din        ,
    output	            din_vld          
);
wire     [7:0]      data ;
wire     	        rdreq;
wire             	wrreq;
wire            	empty;
wire          	    full ;
wire     [7:0]      q    ;
wire     [7:0]      usedw;
reg                 flag ;

assign data=dout;
assign wrreq=dout_vld&&~full;

assign din=q;

//flag
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag<=0;
    end
    else if(usedw>7) begin  //存滿8個字節(jié)拉高flag
        flag<=1;
    end
    else if (empty) begin
        flag<=0;
    end
end

assign rdreq=flag&&ready&&~empty;  
assign din_vld=rdreq;   //每次將din_vld拉高一個周期,輸出一字節(jié)數(shù)據(jù)

fifo	fifo_inst (
	.aclr        ( ~rst_n    ),     //復(fù)位信號取反
	.clock       ( clk       ),     //系統(tǒng)時鐘  
	.data        ( data      ),     //寫入數(shù)據(jù)     
	.rdreq       ( rdreq     ),     //讀使能
	.wrreq       ( wrreq     ),     //寫使能
	.empty       ( empty     ),     //fifo為空信號
	.full        ( full      ),     //fifo存滿信號
	.q           ( q         ),     //讀出數(shù)據(jù)
	.usedw       ( usedw     )      //可用數(shù)據(jù)量
	);

endmodule //control

uart_tx:

module uart_tx (
    input  wire         clk,
    input  wire         rst_n,
    input  wire [7:0]   din,
    input  wire         din_vld,
    output reg          tx,
    output reg          ready
);
//定義一個寄存器來鎖存 din_vld 時的din
reg [9:0]       data;

//波特率計數(shù)器
reg [8:0]       cnt_bps;
wire            add_cnt_bps;
wire            end_cnt_bps;

//比特計數(shù)器
reg [4:0]       cnt_bit;
wire            add_cnt_bit;
wire            end_cnt_bit;

reg             flag;   //計數(shù)器開啟標(biāo)志位

parameter       BPS_115200=434;  //發(fā)送一bit數(shù)據(jù)需要的周期數(shù)

//data
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        data<=0;
    end
    else if(din_vld) begin
        data<={1'b1,din,1'b0};   //拼接起始位和停止位
    end
    else
        data<=data;
end

//發(fā)送數(shù)據(jù) tx
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        tx<=1'b1;
    end
    else if(cnt_bps==1) begin
        tx<=data[cnt_bit];
    end
end

//flag
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        flag<=0;
    end
    else if(din_vld) begin
        flag<=1;
    end
    else if(end_cnt_bit) begin   //發(fā)送完成關(guān)閉計數(shù)器
        flag<=0;
    end
    else
        flag<=flag;
end

//ready
always @(*) begin
    if (!rst_n) begin
        ready<=1;
    end
    else if(flag) begin
        ready<=0;
    end
    else begin
        ready<=1;
    end
end

//cnt_bps
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_bps<=0;
    end
    else if(add_cnt_bps) begin
        if (end_cnt_bps) begin
            cnt_bps<=0;
        end
        else
            cnt_bps<=cnt_bps+1;
    end
end

assign add_cnt_bps=flag;
assign end_cnt_bps=add_cnt_bps&&cnt_bps==BPS_115200-1;

//cnt_bit
always @(posedge clk or negedge rst_n) begin
    if (!rst_n) begin
        cnt_bit<=0;
    end
    else if(add_cnt_bit) begin
        if (end_cnt_bit) begin
            cnt_bit<=0;
        end
        else
            cnt_bit<=cnt_bit+1;
    end
end

assign add_cnt_bit=end_cnt_bps;
assign end_cnt_bit=add_cnt_bit&&cnt_bit==9;

endmodule //uart_tx

3.仿真與分析

testbench:

`timescale 1ns/1ps
module tb_uart ();
reg         clk;
reg         rst_n;
reg [7:0]   din;
reg         din_vld;
wire        tx_r;   //用來連接上位機的tx和從機的rx
wire        rx;

parameter       CYCLE=20;

//例化從機(頂層模塊,包含了一個uart_rx和一個uart_tx)
uart uart(
    .clk            (clk),
    .rst_n          (rst_n),
    .rx             (tx_r),    //接收
    .tx             (tx)     //發(fā)送
);

//例化上位機(用來給從機發(fā)送數(shù)據(jù))
uart_tx uart_tx(
    .clk              (clk),
    .rst_n            (rst_n),
    .din              (din),
    .din_vld          (din_vld),
    .tx               (tx_r)
);

always #(CYCLE/2)  clk=~clk;

initial begin
    clk=1;
    rst_n=1;
    #200;
    rst_n=0;
    din_vld=0;
    #(CYCLE*10);
    rst_n=1;

    send(8'h11);
    send(8'h22);
    send(8'h33);
    send(8'h44);
    send(8'h55);
    send(8'h66);
    send(8'h77);
    send(8'h88);
    #2000000;
    $stop;

end

task send;
    input [7:0] send_data;
    begin
        din=send_data;
        din_vld=1;
        #CYCLE;
        din_vld=0;
        #(CYCLE*434*22);
    end
endtask

endmodule //tb_uart_tx

分析:
【FPGA】UART串口通信---基于FIFO
1.上位機發(fā)送數(shù)據(jù)到FPGA之后由FPGA的接收模塊將數(shù)據(jù)dout數(shù)據(jù)有效信號dout_vld輸出給FIFO緩存
2.dout_vld作為寫使能信號,在寫使能開啟的時候存儲dout
【FPGA】UART串口通信---基于FIFO
3.在FIFO中存儲的數(shù)據(jù)大于7個的時候開啟讀使能,因為FIFO模式設(shè)置的前顯模式,所以在讀使能生效前,第一位數(shù)據(jù)就有效了,也就是時序圖中的q信號:8’h11

【FPGA】UART串口通信---基于FIFO

然后來看發(fā)送數(shù)據(jù):
【FPGA】UART串口通信---基于FIFO
箭頭處,din_vld拉高一個周期,目的是為了在我們發(fā)送完一幀數(shù)據(jù)之前,只鎖存一次數(shù)據(jù),保證發(fā)送一幀數(shù)據(jù)期間數(shù)據(jù)不改變,將數(shù)據(jù)din拼接起始位和停止位鎖存到data

三丶上板驗證

因為設(shè)置的FIFO存儲滿8個數(shù)據(jù)才開始讀數(shù)據(jù),所以這里看到發(fā)送8’h88之后才收到數(shù)據(jù)?。?!

四丶源碼

https://github.com/xuranww/uart_fifo.git

參考文章:
1.https://www.cnblogs.com/xuqing125/p/8337586.html
2.https://blog.csdn.net/QWERTYzxw/article/details/121295258


  1. 緩沖區(qū)(Buffer)就是在內(nèi)存中預(yù)留指定大小的存儲空間用來對I/O的數(shù)據(jù)做臨時存儲,這部分預(yù)留的內(nèi)存空間叫緩沖區(qū)。
    使用緩沖區(qū)有兩個好處:
    ①減少實際物理讀寫次數(shù)
    ②緩沖區(qū)在創(chuàng)建時就被分配內(nèi)存,這塊內(nèi)存區(qū)域一直被重用,可以減少動態(tài)分配和回收內(nèi)存的次數(shù) ??文章來源地址http://www.zghlxwxcb.cn/news/detail-412761.html

到了這里,關(guān)于【FPGA】UART串口通信---基于FIFO的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • 【FPGA】UART串口通信——奇偶校驗實現(xiàn)

    【FPGA】UART串口通信——奇偶校驗實現(xiàn)

    奇偶校驗位是基于uart的數(shù)據(jù)上進(jìn)行一個判斷 奇校驗:數(shù)據(jù)1個數(shù)為奇時,校驗為0,反之為1 偶校驗:數(shù)據(jù)0個數(shù)為偶時,校驗為0,反之為1 Uart回環(huán)在之前已經(jīng)實現(xiàn),現(xiàn)在需要基于uart增加一個奇偶校驗位的需求 uart及代碼:https://blog.csdn.net/weixin_59150966/article/details/128005066?spm=10

    2024年02月11日
    瀏覽(21)
  • FPGA 串口通信(uart)初探篇(含源代碼)

    FPGA 串口通信(uart)初探篇(含源代碼)

    一、UART 串口通信,說實話是日常生活中很常見的一種9針型的主機和顯示屏之間的通信模式。本次博客,只為自己復(fù)盤相關(guān)知識,初學(xué)者,錯誤較多,請多指教。所以本文參考(一)FPGA之串口通信(UART)_fpga uart-CSDN博客 而編著的。 FPGA是一種可編程的邏輯器件,用于各種數(shù)字電

    2024年04月14日
    瀏覽(40)
  • (五)零基礎(chǔ)學(xué)懂FPGA中的串口通信(UART)

    (五)零基礎(chǔ)學(xué)懂FPGA中的串口通信(UART)

    此篇為專欄 《FPGA學(xué)習(xí)筆記》 的第五篇,記錄我的學(xué)習(xí)FPGA的一些開發(fā)過程和心得感悟,剛接觸FPGA的朋友們可以先去此專欄置頂 《FPGA零基礎(chǔ)入門學(xué)習(xí)路線》來做最基礎(chǔ)的掃盲。 本篇內(nèi)容基于筆者實際開發(fā)過程和正點原子資料撰寫,將會詳細(xì)講解此FPGA實驗的全流程, 誠摯 地

    2024年02月04日
    瀏覽(26)
  • uart串口環(huán)回(加FIFO)

    uart串口環(huán)回(加FIFO)

    UART(universal asynchronous receiver-transmitter)是一種采用異步串行通信方式的通用異步收發(fā)傳輸器。 定義如上,那么出現(xiàn)問題了,什么叫異步串行通信?請關(guān)注下文原理。 1.1同步通信 發(fā)送方發(fā)送出數(shù)據(jù)后,等接收方響應(yīng)后才發(fā)送下一個數(shù)據(jù) 1.2異步通信 發(fā)送方發(fā)出數(shù)據(jù)后,不等接

    2024年01月24日
    瀏覽(16)
  • 基于FPGA的超聲波測距——UART串口輸出

    基于FPGA的超聲波測距——UART串口輸出

    環(huán)境: 1、Quartus18.0 2、vscode 3、板子型號:EP4CE10F17C8 4、超聲波模塊:HC_SR04 要求: 使用 EP4CE10F17C8開發(fā)板驅(qū)動 超聲波檢測模塊(HC_SR04 ),并將所測得數(shù)據(jù)顯示到串口助手上。 HC-SR04超聲波測距模塊可提供2cm-400cm的非接觸式距離感測功能,測距精度可達(dá)高到3mm;模塊包括超聲波發(fā)

    2024年02月14日
    瀏覽(18)
  • 【單片機】基于STM32的UART串口通信

    【單片機】基于STM32的UART串口通信

    簡單講解一下UART通信協(xié)議,以及UART能夠?qū)崿F(xiàn)的一些功能,還有有關(guān)使用STM32CubeMX來配置芯片的一些操作。實驗內(nèi)容基于 正點原子精英板 開發(fā)板,單片機芯片為 STM32F103ZET6 。 在后面我會以我使用的STM32F429開發(fā)板來舉例講解(其他STM32系列芯片大多數(shù)都可以按照這些步驟來操作

    2024年01月17日
    瀏覽(96)
  • 基于樹莓派4B與STM32的UART串口通信實驗(代碼開源)

    基于樹莓派4B與STM32的UART串口通信實驗(代碼開源)

    前言: 本文為手把手教學(xué) 樹莓派4B與 STM32 的 UART 通訊 ,本次項目采用 樹莓派4B 與? STM32? 進(jìn)行串口通訊,將彼此的數(shù)據(jù)進(jìn)行互相傳輸。本篇博客同時提供了基于 YOLOv5-Lite 的目標(biāo)檢測數(shù)據(jù)聯(lián)動,即將 樹莓派4B 檢測到的信息發(fā)送至 STM32 ,后續(xù)可以通過這些信息進(jìn)行各種需求上

    2024年02月16日
    瀏覽(38)
  • UART串口通信協(xié)議

    UART串口通信協(xié)議

    串行通信分為兩種方式: 同步串行通信 和 異步串行通信 。 同步串行通信需要通信雙方在同一時鐘的控制下,同步傳輸數(shù)據(jù)。 異步串行通信是指通信雙方使用各自的時鐘控制數(shù)據(jù)的發(fā)送和接收過程。 通用異步收發(fā)傳輸器(Universal Asynchronous Receiver/Transmitter,UART)是一種 全雙

    2024年02月03日
    瀏覽(19)
  • UART串口通信實驗

    UART串口通信實驗

    不管是單片機開發(fā)還是嵌入式 Linux 開發(fā),串口都是最常用到的外設(shè)。 可以通過串口將開發(fā)板與電腦相連,然后在電腦上通過串口調(diào)試助手來調(diào)試程序。 還有很多模塊,比如藍(lán)牙、GPS、GPRS等都使用串口與主控進(jìn)行通信。 串口全稱串行接口,通常也叫做COM接口,,串行接口指

    2024年02月08日
    瀏覽(21)
  • 串口通信(UART)

    串口通信(UART)

    串口是一種應(yīng)用十分廣泛的通訊接口,串口成本低、容易使用、通信線路簡單,可實現(xiàn)兩個設(shè)備的互相通信。 單片機的串口可以使單片機與單片機、單片機與電腦、單片機與各式各樣的模塊互相通信,極大的擴(kuò)展了單片機的應(yīng)用范圍,增強了單片機系統(tǒng)的硬件實力。 51單片機

    2024年02月07日
    瀏覽(17)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包