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

news2024/10/6 1:11:44

一、实验要求

实现同步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 )begin
              if ( cnt == delay -1 )
                   cnt <= cnt ;
              else
                   cnt <= cnt +1 ;
         end
         else
         cnt <= 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_flag
    wire            start_flag     ;
    reg              rx_reg1        ;
    reg              rx_reg2        ;
    
    always@(posedge sys_clk )
         if(!rst_n)begin
            rx_reg1 <= 1 ;
            rx_reg2 <= 1 ;
         end
         else
             begin
                  rx_reg1 <= rx_data ;
                  rx_reg2 <= rx_reg1 ;
             end
    assign  start_flag = ~rx_reg1 & rx_reg2  ;
    
    ///rx_flag
    reg               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 ;
         else
            rx_flag <= rx_flag  ;
    
    ///cnt434
     always@(posedge sys_clk )
          if(!rst_n)
             cnt <= 0 ;
          else if ( rx_flag == 1 )begin
               if ( cnt == COUNT -1 )
                    cnt <= 0 ;
               else
                    cnt <= cnt +1 ;
          end
          else
          cnt <= 0 ;
     
     //cnt_bit
     always@(posedge sys_clk )
           if(!rst_n)
              cnt_bit <= 0 ;
           else if ( rx_flag == 1 )begin
                if ( cnt == COUNT - 1 )begin
                    if ( cnt_bit == 10 )
                         cnt_bit <= 0 ;
                    else
                         cnt_bit <= cnt_bit +1 ;
                end
                else
                cnt_bit <= cnt_bit ;                   
           end
           else
           cnt_bit <= 0 ;
    
    //data_reg
    reg[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 )begin
              if ( cnt_bit > 0 && cnt_bit < 10 && cnt == MID - 1 )
                  data_reg[ cnt_bit - 1 ] <= rx_data ;
              else
                  data_reg <= data_reg  ;
         end
         else
         data_reg <= 0 ;
  
  ///check
     reg                 check  ;
     parameter          MODE_CHECK = 0 ;     
     always@(posedge sys_clk )
          if(!rst_n)
             check <= 0 ;
          else if ( rx_flag == 1 )begin
               if ( cnt_bit == 10 )
                   check <= ^data_reg ;
               else
                   check <= check ;
          end
          else
          check <= 0 ;
   
   //uart_data
     always@(posedge sys_clk )
          if(!rst_n)
            uart_data <= 0 ;
          else if ( rx_flag == 1 )begin
               if ( cnt_bit == 10 && cnt == MID - 1 && check == MODE_CHECK )
                    uart_data <= data_reg[7:0] ;
               else
                    uart_data <= uart_data ;
          end
          else
          uart_data <= uart_data  ;
     
     ///rx_done
     always@(posedge sys_clk )
          if(!rst_n)
             rx_done <= 0 ;
          else if ( rx_flag == 1 )begin
               if ( cnt_bit == 10 && cnt == COUNT -1 )
                    rx_done <= 1 ;
               else
                    rx_done <= 0 ;
          end
          else
          rx_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_flag
    reg              tx_reg1 ;
    reg              tx_reg2 ;
    wire            start_flag ;
    
    always@(posedge sys_clk )
         if(!rst_n)begin
            tx_reg1 <= 0 ;
            tx_reg2 <= 0 ;
            end
         else
             begin
                 tx_reg1 <= tx_start  ;
                 tx_reg2 <= tx_reg1  ;
             end
    assign  start_flag = tx_reg1 & ~tx_reg2 ;
    
    //tx_flag
    reg               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 ;
         else
            tx_flag <= tx_flag ;
    
   ///cnt
   always@(posedge sys_clk )
        if(!rst_n)
           cnt <= 0 ;
        else if ( tx_flag == 1 )begin
             if ( cnt == COUNT -1 )
                  cnt <= 0 ;
             else
                  cnt <= cnt +1 ;
        end
        else
        cnt <= 0 ;
    
    ///cnt_bit 
    always@(posedge sys_clk )
         if(!rst_n)
            cnt_bit <= 0 ;
         else if ( tx_flag == 1 )begin
              if ( cnt == COUNT -1 )begin
                  if ( cnt_bit == 10 )
                       cnt_bit <= 0 ;
                  else
                       cnt_bit <= cnt_bit +1 ;
              end
              else
              cnt_bit <= cnt_bit ;
         end
         else
         cnt_bit <= 0 ;
    
    //tx_data
    parameter               MODE_CHECK = 0 ;
    always@(posedge sys_clk )
         if(!rst_n)        //cnt_bit:[0] 12345678 [9] [10]
            tx_data <= 0 ; //uart_data: 01234567
         else if ( tx_flag == 1 )begin
              if ( 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 ;
              else
                   tx_data <= tx_data ;    
         end
         else
         tx_data <= 1 ;
    
    ///tx_done
     always@(posedge sys_clk )
          if(!rst_n)
             tx_done <= 0 ;
          else if ( tx_flag == 1 )begin
               if ( cnt_bit == 10 && cnt == COUNT -1 )
                    tx_done <= 1 ;
               else
                    tx_done <= 0 ;
          end
          else
          tx_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  ;
    
    //state1
    always@(posedge sys_clk )
         if(!rst_n)
            cur_state <= IDLE ;
         else
            cur_state <= next_state ;
     
     //state2
     always@(*)
           case(cur_state)
                 IDLE  :
                        begin
                            next_state = WRITE ;
                        end
                 WRITE :
                        begin
                            if( full == 1 )
                               next_state = WAIT ;
                            else
                               next_state = cur_state ;
                        end
                 WAIT  :
                        begin
                            if ( key_flag == 1 )
                                next_state = TEXT ;
                            else
                                next_state = cur_state ;
                        end
                 TEXT  :
                        begin
                            if( empty == 1 )
                                next_state = IDLE ;
                            else
                                next_state = cur_state ;
                        end
           default:;
           endcase
    
    ///state3
     always@(posedge sys_clk )
          if(!rst_n)begin
              din   <= 0 ;
              wr_en <= 0 ;       
              rd_en <= 0 ; 
              fifo_out <= 0 ;
              tx_start <= 0 ;      
          end
          else
              case(cur_state)
                   IDLE  :
                           begin
                                 din   <= 0 ;     
                                 wr_en <= 0 ;     
                                 rd_en <= 0 ;     
                                 fifo_out <= 0 ;  
                                 tx_start <= 0 ;  
                           end
                   WRITE :
                           begin
                               if ( rx_done )begin
                                   wr_en <= 1 ;     
                                   din <= uart_data ;
                                   end
                                else
                                   wr_en <= 0 ;
                           end
                   WAIT  :
                          begin
                               tx_start <= 0 ;
                               if (key_flag == 1 ) //只有一个时钟周期能读完吗?
                                   rd_en <= 1 ;    //答:此时uart_data是并行数据,传输仅需1个时钟周期
                                else
                                   rd_en <= 0 ;
                          end
                   TEXT  :  
                          begin
                               if(valid)
                                  tx_start <= 1 ;
                               else
                                  tx_start <= 0 ;
                               
                               if(tx_done)
                                  rd_en <= 1 ;
                               else
                                  rd_en <= 0 ;
                                  
                               if(valid)
                                  fifo_out <= dout ;
                               else
                                  fifo_out <= fifo_out ;
                          end
              
              default:;
              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_debounce
  wire              key_flag  ;
  key_debounce key_debounce_u1(
                              .    sys_clk  (sys_clk )  ,
                              .    rst_n    (rst_n   )  ,
                              .    key      (key     )  ,
                              .    key_flag (key_flag)  
    );
 
 ///uart_rx
 wire       [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  )
    );
 
 ///fifo
   common_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    ;
   
   initial
          begin
               sys_clk = 0 ;
               rst_n   = 0 ;
               key     = 1 ;
               #10
               rst_n   = 1 ;
               #200000
               key     = 0 ;
          end
   always  #1  sys_clk = ~sys_clk ;
   
   initial
          begin
               uart_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   ;
       begin
            rx_data = 1 ; ///空闲位初始
            #20
            rx_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)                       ;
       end
   endtask

   
 
 TOP TOP_1(
            .     sys_clk (sys_clk)   ,
            .     rst_n   (rst_n  )   ,
            .     key     (key    )   ,
            .     rx_data (rx_data)   ,
            .     tx_data (tx_data) 
    );






endmodule

实验结果:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1903743.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python编程学习笔记(1)--- 变量和简单数据类型

1、变量 在学习编程语言之前&#xff0c;所接触的第一个程序&#xff0c;绝大多数都是&#xff1a; print("Hello world!") 接下来尝试使用一个变量。在代码中的开头添加一行代码&#xff0c;并对第二行代码进行修改&#xff0c;如下&#xff1a; message "…

Github 2024-07-07php开源项目日报 Top9

根据Github Trendings的统计,今日(2024-07-07统计)共有9个项目上榜。根据开发语言中项目的数量,汇总情况如下: 开发语言项目数量PHP项目9Blade项目2JavaScript项目1Laravel:表达力和优雅的 Web 应用程序框架 创建周期:4631 天开发语言:PHP, BladeStar数量:75969 个Fork数…

什么时候考虑将mysql数据迁移到ES?

文章目录 对ES的一些疑问问题1:ES相比mysql本身有哪些优势&#xff1f;问题2:哪些场景适合用ES而不是mysql&#xff1f;问题3:mysql逐行扫描&#xff0c;根据过滤条件检查记录中对应字段是否满足要求属于正排索引&#xff0c;根据二叉树索引检索记录的方式属于正排索引还是倒排…

LeetCode 189.轮转数组 三段逆置 C写法

LeetCode 189.轮转数组 C写法 三段逆置 思路: 三段逆置方法:先逆置前n-k个 再逆置后k个 最后整体逆置 由示例1得&#xff0c;需要先逆置1,2,3,4 再逆置5,6,7&#xff0c;最后前n-k个与后k个逆置 代码 void reverse(int*num, int left, int right) //逆置函数 { while(left …

XLSX + LuckySheet + LuckyExcel + Web Worker实现前端的excel预览

文章目录 功能简介简单代码实现web worker 版本效果参考 功能简介 通过LuckyExcel的transformExcelToLucky方法&#xff0c; 我们可以把一个文件直接转成LuckySheet需要的json字符串&#xff0c; 之后我们就可以用LuckySheet预览excelLuckyExcel只能解析xlsx格式的excel文件&a…

mac|idea导入通义灵码插件

官方教程&#xff1a;通义灵码下载安装指南_智能编码助手_AI编程_云效(Apsara Devops)-阿里云帮助中心 下载插件&#xff1a; ⇩ TONGYI Lingma - JetBrains 结果如下&#xff1a; 选择apply、ok&#xff0c;会出现弹窗&#xff0c;点击登录 可以实现&#xff1a;生成单元测…

SQL Server特性

一、创建表 在sql server中使用create table来创建新表。 create table Customers( id int primary key identity(1,1), name varchar(5) ) 该表名为Customers其中包含了2个字段&#xff0c;分别为id&#xff08;主键&#xff09;以及name。 1、数据类型 整数类型&#xff…

【TB作品】51单片机 Proteus仿真 00002仿真-智能台灯色调倒计时光强

实验报告&#xff1a;基于51单片机的智能台灯控制系统 背景 本实验旨在设计一个基于51单片机的智能台灯控制系统&#xff0c;该系统可以通过按键进行手动控制&#xff0c;并能根据环境光强度自动调节台灯亮度。此外&#xff0c;系统还具备倒计时关灯功能。 器件连接 51单片…

latex英文转中文word,及一些latex相关工具分享

前言&#xff1a;想要转换latex生成的英文pdf文件为中文word文件 一、主要步骤 1、文字翻译&#xff1a;直接使用谷歌翻译等辅助将英文翻译成中文即可&#xff1b; 2、图片&#xff1a; 使用latex时一般保存的.png&#xff0c;.bmp格式图片可以直接插入word, 但是.eps或者 .p…

期末成绩发布方式

期末考试结束后&#xff0c;成绩单的发放总是让老师们头疼不已。想象一下&#xff0c;每个学生的成绩都需要老师一个个私信给家长&#xff0c;不仅耗时耗力&#xff0c;而且极易出错。 在传统的成绩单发放方式中&#xff0c;老师往往需要通过电子邮件、短信或者微信等方式&…

使用Keil将STM32部分程序放在RAM中运行

手动分配RAM区域,新建.sct文件,定义RAM_CODE区域,并指定其正确的起始地址和大小。 ; ************************************************************* ; *** Scatter-Loading Description File generated by uVision *** ; ************************************************…

高考志愿填报千万要注意这四点

在高考志愿填报过程中&#xff0c;确实有很多需要留心的点。我为你总结了四个关键点&#xff0c;希望能帮助你顺利完成志愿填报&#xff1a; 1、学校提供的支持 学校作为学生志愿填报咨询服务的主阵地&#xff0c;应提供体系化和制度化的支持。包括及时关注并传达政策动向和相…

ubuntu下运行程序时提示缺库问题的有效解决方法

目录 一、问题现象二、解决方式三、总结 一、问题现象 当我们平时在ubuntu上运行一个程序时时长会遇到如下情况&#xff0c;含义为本机缺少执行程序需要的库 这时候我们可能会根据缺少的库使用apt install 库名的模糊名字 进行安装&#xff0c;然后再去运行&#xff0c;此时可…

vue3+antd 实现文件夹目录右键菜单功能

原本的目录结构&#xff1a; 右键菜单&#xff1a; 点击菜单以后会触发回调&#xff1a; 完整的前端代码&#xff1a; <template><a-directory-treev-model:expandedKeys"expandedKeys"v-model:selectedKeys"selectedKeys"multipleshow-li…

C语言下结构体、共用体、枚举类型的讲解

主要内容 结构体结构体数组结构体指针包含结构体的结构链表链表相关操作共用体枚举类型 结构体 结构体的类型的概念 结构体实现步骤 结构体变量的声明 struct struct 结构体名{ 数据类型 成员名1; 数据类型 成员名2; ..…

【Unity】unity学习扫盲知识点

1、建议检查下SystemInfo的引用。这个是什么 Unity的SystemInfo类提供了一种获取关于当前硬件和操作系统的信息的方法。这包括设备类型&#xff0c;操作系统&#xff0c;处理器&#xff0c;内存&#xff0c;显卡&#xff0c;支持的Unity特性等。使用SystemInfo类非常简单。它的…

1999-2022年企业持续绿色创新水平数据

企业持续绿色创新水平数据为研究者提供了评估企业在绿色技术领域创新持续性和能力的重要视角。以下是对企业持续绿色创新水平数据的介绍&#xff1a; 数据简介 定义&#xff1a;企业持续绿色创新水平反映了企业在一定时期内绿色专利申请的持续性和创新能力。计算方法&#xf…

【Linux】进程的概念 + 查看进程

前言&#xff1a; 在前面我们学习了Liunx的基本指令和权限相关知识&#xff0c;还有基本工具的使用&#xff0c;有了以上的基础知识我们本章将正式接触Linux操作系统。 目录 1.冯诺依曼体系结构1.1 内存存在的意义1.2 程序加载到内存的含义1.3 程序的预加载&#xff1a; 2 .认识…

英国“王曼爱华”指的是哪几所高校?中英双语介绍

中文版 英国“王曼爱华”指的是伦敦大学国王学院、曼彻斯特大学、爱丁堡大学和华威大学这四所院校。以下是对伦敦大学国王学院、曼彻斯特大学、爱丁堡大学和华威大学这四所英国顶尖大学的详细介绍&#xff0c;包括它们的建校历史、专业优势、优秀校友和地理位置。 伦敦大学国…

图像增强 目标检测 仿射变换 图像处理 扭曲图像

1.背景 在目标检测中&#xff0c;需要进行图像增强。这里的代码模拟了旋转、扭曲图像的功能&#xff0c;并且在扭曲的时候&#xff0c;能够同时把标注的结果也进行扭曲。 这里忽略了读取xml的过程&#xff0c;假设图像IMG存在对应的标注框&#xff0c;且坐标为左上、右下两个…