当前位置: 首页> 房产> 政策 > Xilinx FPGA:vivado串口输入输出控制fifo中的数据

Xilinx FPGA:vivado串口输入输出控制fifo中的数据

时间:2025/7/11 18:37:34来源:https://blog.csdn.net/loveyousosad/article/details/140237601 浏览次数:1次

一、实验要求

实现同步FIFO回环测试,通过串口产生数据,写入到FIFO内部,当检测到按键信号到来,将FIFO里面的数据依次读出。

二、信号流向图

三、状态转换图

四、程序设计

(1)按键消抖模块

`timescale 1ns / 1ps
module key_debounce(input                  sys_clk    ,input                  rst_n      ,input                  key        ,output                 key_flag   );
//    parameter         delay = 10_000_00 ;parameter         delay = 10_0;//00_00 ; //测试用reg[19:0]         cnt      ;always@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( key == 0 )beginif ( cnt == delay -1 )cnt <= cnt ;elsecnt <= cnt +1 ;endelsecnt <= 0 ;assign key_flag = ( cnt == delay - 2 )?1:0 ;endmodule

(2)接收端模块

`timescale 1ns / 1ps
module rx_uart(input                    sys_clk   ,input                    rst_n     ,input                    rx_data   ,//[0]起始位 [12345678]数据位 [9]校验位 [10]停止位output     reg[7:0]     uart_data ,output     reg           rx_done  );parameter              SYSCLK = 50_000_000 ;parameter              Baud   = 115200     ; parameter              COUNT  = SYSCLK/Baud; parameter              MID    = COUNT/2    ; //start_flagwire            start_flag     ;reg              rx_reg1        ;reg              rx_reg2        ;always@(posedge sys_clk )if(!rst_n)beginrx_reg1 <= 1 ;rx_reg2 <= 1 ;endelsebeginrx_reg1 <= rx_data ;rx_reg2 <= rx_reg1 ;endassign  start_flag = ~rx_reg1 & rx_reg2  ;///rx_flagreg               rx_flag   ;reg[4:0]          cnt_bit   ;reg[9:0]          cnt       ;always@(posedge sys_clk )if(!rst_n)rx_flag <= 0 ;else if ( start_flag == 1 )rx_flag <= 1 ;else if ( cnt_bit == 10 && cnt == COUNT -1 )rx_flag <= 0 ;elserx_flag <= rx_flag  ;///cnt434always@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( rx_flag == 1 )beginif ( cnt == COUNT -1 )cnt <= 0 ;elsecnt <= cnt +1 ;endelsecnt <= 0 ;//cnt_bitalways@(posedge sys_clk )if(!rst_n)cnt_bit <= 0 ;else if ( rx_flag == 1 )beginif ( cnt == COUNT - 1 )beginif ( cnt_bit == 10 )cnt_bit <= 0 ;elsecnt_bit <= cnt_bit +1 ;endelsecnt_bit <= cnt_bit ;                   endelsecnt_bit <= 0 ;//data_regreg[8:0]             data_reg  ; always@(posedge sys_clk )if(!rst_n)         ///cnt_bit : [0] 12345678 [9] [10]data_reg <= 0 ;///data_reg : 01234567 [8]else if ( rx_flag == 1 )beginif ( cnt_bit > 0 && cnt_bit < 10 && cnt == MID - 1 )data_reg[ cnt_bit - 1 ] <= rx_data ;elsedata_reg <= data_reg  ;endelsedata_reg <= 0 ;///checkreg                 check  ;parameter          MODE_CHECK = 0 ;     always@(posedge sys_clk )if(!rst_n)check <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit == 10 )check <= ^data_reg ;elsecheck <= check ;endelsecheck <= 0 ;//uart_dataalways@(posedge sys_clk )if(!rst_n)uart_data <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit == 10 && cnt == MID - 1 && check == MODE_CHECK )uart_data <= data_reg[7:0] ;elseuart_data <= uart_data ;endelseuart_data <= uart_data  ;///rx_donealways@(posedge sys_clk )if(!rst_n)rx_done <= 0 ;else if ( rx_flag == 1 )beginif ( cnt_bit == 10 && cnt == COUNT -1 )rx_done <= 1 ;elserx_done <= 0 ;endelserx_done <= 0 ;endmodule

(3)发送端模块

`timescale 1ns / 1ps
module tx_uart(input                 sys_clk    ,input                 rst_n      ,input     [7:0]       fifo_out  ,input                 tx_start    ,output   reg          tx_data    ,output   reg          tx_done );parameter                 SYSCLK = 50_000_000 ; parameter                 Baud   = 115200     ;    parameter                 COUNT  = SYSCLK/Baud;   parameter                 MID    = COUNT/2    ;//start_flagreg              tx_reg1 ;reg              tx_reg2 ;wire            start_flag ;always@(posedge sys_clk )if(!rst_n)begintx_reg1 <= 0 ;tx_reg2 <= 0 ;endelsebegintx_reg1 <= tx_start  ;tx_reg2 <= tx_reg1  ;endassign  start_flag = tx_reg1 & ~tx_reg2 ;//tx_flagreg               tx_flag  ;reg[4:0]          cnt_bit  ;reg[9:0]          cnt      ;always@(posedge sys_clk )if(!rst_n)tx_flag <= 0 ;else if ( start_flag == 1 )tx_flag <= 1 ;else if ( cnt_bit == 10 && cnt == COUNT -1 )tx_flag <= 0 ;elsetx_flag <= tx_flag ;///cntalways@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( tx_flag == 1 )beginif ( cnt == COUNT -1 )cnt <= 0 ;elsecnt <= cnt +1 ;endelsecnt <= 0 ;///cnt_bit always@(posedge sys_clk )if(!rst_n)cnt_bit <= 0 ;else if ( tx_flag == 1 )beginif ( cnt == COUNT -1 )beginif ( cnt_bit == 10 )cnt_bit <= 0 ;elsecnt_bit <= cnt_bit +1 ;endelsecnt_bit <= cnt_bit ;endelsecnt_bit <= 0 ;//tx_dataparameter               MODE_CHECK = 0 ;always@(posedge sys_clk )if(!rst_n)        //cnt_bit:[0] 12345678 [9] [10]tx_data <= 0 ; //uart_data: 01234567else if ( tx_flag == 1 )beginif ( cnt_bit > 0 && cnt_bit < 9 && cnt == MID -1 )tx_data <= fifo_out[ cnt_bit -1 ] ;else if ( cnt_bit == 0 )tx_data <= 0 ;else if ( cnt_bit == 10)tx_data <= 1 ;else if ( cnt_bit == 9 )tx_data <= ( MODE_CHECK == 0 )?^fifo_out:~^fifo_out ;elsetx_data <= tx_data ;    endelsetx_data <= 1 ;///tx_donealways@(posedge sys_clk )if(!rst_n)tx_done <= 0 ;else if ( tx_flag == 1 )beginif ( cnt_bit == 10 && cnt == COUNT -1 )tx_done <= 1 ;elsetx_done <= 0 ;endelsetx_done <= 0 ;endmodule

(4)fifo控制模块

`timescale 1ns / 1ps
module common_fifo_ctrl(input                   sys_clk    ,input                   rst_n      ,input     [7:0]         uart_data  ,input                   rx_done    ,input                   tx_done    ,input                   key_flag   ,output     reg          tx_start   ,output     reg[7:0]     fifo_out   );reg  [7 : 0] din  ;       reg  wr_en        ;     reg  rd_en        ;     wire [7 : 0] dout      ; wire full              ;wire wr_ack            ;wire empty             ;wire valid             ;wire [3 : 0] data_count;localparam                  IDLE   = 3'd0 ;localparam                  WRITE  = 3'd1 ;localparam                  WAIT   = 3'd2 ;localparam                  TEXT   = 3'd3 ;reg[2:0]                    cur_state   ;reg[2:0]                    next_state  ;//state1always@(posedge sys_clk )if(!rst_n)cur_state <= IDLE ;elsecur_state <= next_state ;//state2always@(*)case(cur_state)IDLE  :beginnext_state = WRITE ;endWRITE :beginif( full == 1 )next_state = WAIT ;elsenext_state = cur_state ;endWAIT  :beginif ( key_flag == 1 )next_state = TEXT ;elsenext_state = cur_state ;endTEXT  :beginif( empty == 1 )next_state = IDLE ;elsenext_state = cur_state ;enddefault:;endcase///state3always@(posedge sys_clk )if(!rst_n)begindin   <= 0 ;wr_en <= 0 ;       rd_en <= 0 ; fifo_out <= 0 ;tx_start <= 0 ;      endelsecase(cur_state)IDLE  :begindin   <= 0 ;     wr_en <= 0 ;     rd_en <= 0 ;     fifo_out <= 0 ;  tx_start <= 0 ;  endWRITE :beginif ( rx_done )beginwr_en <= 1 ;     din <= uart_data ;endelsewr_en <= 0 ;endWAIT  :begintx_start <= 0 ;if (key_flag == 1 ) //只有一个时钟周期能读完吗?rd_en <= 1 ;    //答:此时uart_data是并行数据,传输仅需1个时钟周期elserd_en <= 0 ;endTEXT  :  beginif(valid)tx_start <= 1 ;elsetx_start <= 0 ;if(tx_done)rd_en <= 1 ;elserd_en <= 0 ;if(valid)fifo_out <= dout ;elsefifo_out <= fifo_out ;enddefault:;endcase//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
fifo_generator_0 fifo1 (.clk(sys_clk ),                // input wire clk.srst(~rst_n),              // input wire srst.din(din),                // input wire [7 : 0] din.wr_en(wr_en),            // input wire wr_en.rd_en(rd_en),            // input wire rd_en.dout(dout),              // output wire [7 : 0] dout.full(full),              // output wire full.wr_ack(wr_ack),          // output wire wr_ack.empty(empty),            // output wire empty.valid(valid),            // output wire valid.data_count(data_count)  // output wire [3 : 0] data_count
);
// INST_TAG_END ------ End INSTANTIATION Template ---------endmodule

(5)顶层

`timescale 1ns / 1ps
module TOP(input                    sys_clk    ,input                    rst_n      ,input                    key        ,input                    rx_data    ,output                   tx_data  );///key_debouncewire              key_flag  ;key_debounce key_debounce_u1(.    sys_clk  (sys_clk )  ,.    rst_n    (rst_n   )  ,.    key      (key     )  ,.    key_flag (key_flag)  );///uart_rxwire       [7:0]       uart_data  ;wire                   rx_done    ;rx_uart rx_uart_u1(.    sys_clk  ( sys_clk )  ,.    rst_n    ( rst_n   )  ,.    rx_data  ( rx_data )  ,//[0]起始位 [12345678]数据位 [9]校验位 [10]停止位.   uart_data (uart_data)  ,.    rx_done  ( rx_done ) );///uart_tx
wire               tx_done   ;
wire    [7:0]       fifo_out  ;
wire               tx_start  ; 
tx_uart tx_uart_u1(.   sys_clk    (sys_clk  ) ,.   rst_n      (rst_n    ) ,.   fifo_out   (fifo_out ) ,.   tx_start   (tx_start  ) ,.   tx_data    (tx_data  ) ,.   tx_done    (tx_done  ));///fifocommon_fifo_ctrl common_fifo_ctrl_u1(.     sys_clk    (sys_clk  )     ,.     rst_n      (rst_n    )     ,.     uart_data  (uart_data)     ,.     rx_done    (rx_done  )     ,.     tx_done    (tx_done  )     ,.     key_flag   (key_flag )     ,.     tx_start   (tx_start )     ,.     fifo_out   (fifo_out )     );endmodule

五、仿真结果

程序:

`timescale 1ns / 1ps
module test_TOP(  );reg                sys_clk    ;reg                rst_n      ;reg                key        ;reg                rx_data    ;wire               tx_data    ;parameter               SYSCLK = 50_000_000 ;parameter               Baud   = 115200     ;parameter               COUNT  = SYSCLK/Baud;parameter               MID    = COUNT/2    ;initialbeginsys_clk = 0 ;rst_n   = 0 ;key     = 1 ;#10rst_n   = 1 ;#200000key     = 0 ;endalways  #1  sys_clk = ~sys_clk ;initialbeginuart_out ( 8'hCC );uart_out ( 8'hE8 );uart_out ( 8'h18 );uart_out ( 8'h78 );uart_out ( 8'h66 );uart_out ( 8'h1E );uart_out ( 8'hCC );uart_out ( 8'h9F );uart_out ( 8'h66 );uart_out ( 8'h9F );uart_out ( 8'h33 );uart_out ( 8'h1E );uart_out ( 8'hCC );uart_out ( 8'h9F );uart_out ( 8'h18 );uart_out ( 8'h33 );uart_out ( 8'hCC );end//任务函数task            uart_out  ;input    [8:0]    DATA   ;beginrx_data = 1 ; ///空闲位初始#20rx_data = 0 ;#(COUNT*2)    rx_data = DATA[0]  ;#(COUNT*2)    rx_data = DATA[1]  ;#(COUNT*2)    rx_data = DATA[2]  ;#(COUNT*2)    rx_data = DATA[3]  ;#(COUNT*2)    rx_data = DATA[4]  ;#(COUNT*2)    rx_data = DATA[5]  ;#(COUNT*2)    rx_data = DATA[6]  ;#(COUNT*2)    rx_data = DATA[7]  ;#(COUNT*2)    rx_data = 0        ;#(COUNT*2)    rx_data = 1        ;#(COUNT*2)                       ;endendtaskTOP TOP_1(.     sys_clk (sys_clk)   ,.     rst_n   (rst_n  )   ,.     key     (key    )   ,.     rx_data (rx_data)   ,.     tx_data (tx_data) );endmodule

实验结果:

关键字:Xilinx FPGA:vivado串口输入输出控制fifo中的数据

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: