Xilinx FPGA:vivado关于单端ROM的一个只读小实验

一、实验要求

    将生成好的voe文件里的数据使用rom读取出来,采用串口工具发送给电脑(当按键来临时)。

二、程序设计

按键消抖模块:

`timescale 1ns / 1ps
module key_debounce(
  input           sys_clk    ,
  input           rst_n      ,
  input           key        ,
  output          key_flag 
    );
//    parameter              delay = 100_000_0   ; //20ms
    parameter              delay = 100;// 测试用
    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

发送端模块:

`timescale 1ns / 1ps
module uart_tx(
   input                     sys_clk   ,
   input                     rst_n     ,
   input      [7:0]          ram_out   ,
   input                     tx_start  ,
   output      reg           tx_done   ,
   output      reg           tx_data
    );
    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) 
           tx_data <= 0 ;
        else if ( tx_flag == 1 )begin
             if ( cnt_bit > 0 && cnt_bit < 9 )
                  tx_data <= ram_out[cnt_bit -1] ;
             else if ( cnt_bit == 0 )
                  tx_data <= 0 ;
             else if ( cnt_bit == 9 )
                  tx_data <= ( MODE_CHECK == 0 )?^ram_out : ~^ram_out ;
             else if ( cnt_bit == 10 )
                  tx_data <= 1 ;
             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

顶层(ROM)模块:

IP参数:

`timescale 1ns / 1ps
///按键来临时,将rom中的数据读出,并通过tx模块返回给PC端
module rom(
     input            sys_clk    ,
     input            rst_n      ,
     input            key        ,
     output           tx_data  
    );
    wire             key_flag    ;
    wire             tx_done     ;
    reg              tx_start    ;
    reg              ena         ;
    reg[4:0]         addra       ;
    wire[7:0]        douta       ;
    
    always@(posedge sys_clk )
         if(!rst_n)
            addra <= 0 ;
         else if ( tx_done && addra == 15 )
            addra <= 15 ;   ///保持在15,不连续输出
         else if ( tx_done || key_flag )//key_flag 是因为第一个数据要输出,地址要+1
            addra <= addra +1 ;
         else
            addra <= addra ;
            
   always@(posedge sys_clk )
        if(!rst_n)
            ena <= 0 ;
        else if ( key_flag )
            ena <= 1 ;
        else if ( tx_done && addra <= 14 )
            ena <= 1 ;
        else if ( addra == 15 )
            ena <= 0 ;  
        else
            ena <= 0 ; 
    
    always@(posedge sys_clk )
         if (!rst_n)
             tx_start <= 0 ;
         else if ( key_flag )
             tx_start <= 1 ;   ///发送第一个数据
         else if ( tx_done && addra <= 14)///发送后面的数据 
             tx_start <= 1 ;
         else
             tx_start <= 0 ;
   
//----------- Begin Cut here for INSTANTIATION Template ---// INST_TAG
blk_mem_gen_0 rom (
  .clka(sys_clk ),    // input wire clka
  .ena(ena),      // input wire ena
  .addra(addra),  // input wire [3 : 0] addra
  .douta(douta)  // output wire [7 : 0] douta
);
// INST_TAG_END ------ End INSTANTIATION Template ---------
   
key_debounce key_debounce_u1(
                  .      sys_clk  (sys_clk )  ,
                  .      rst_n    (rst_n   )  ,
                  .      key      (key     )  ,
                  .      key_flag (key_flag)
    );
   
uart_tx uart_tx_u1(   
                   .     sys_clk (sys_clk )  ,   
                   .     rst_n   (rst_n   )  ,
                   .     ram_out (douta )  ,
                   .     tx_start(tx_start)  ,
                   .     tx_done (tx_done )  ,
                   .     tx_data (tx_data )
    );



endmodule

三、仿真结果

仿真程序:

`timescale 1ns / 1ps
module test_rom(  );

     reg            sys_clk    ;
     reg            rst_n      ;
     reg            key        ;
     wire           tx_data    ;
     
     initial 
            begin
                   sys_clk = 0 ;
                   rst_n   = 0 ;
                   key     = 1 ;
                   #10   
                   rst_n   = 1 ;
                   #1000
                   key     = 0 ;
            end
  always #1 sys_clk = ~sys_clk ;   


rom rom_1(
     .          sys_clk  (sys_clk)  ,
     .          rst_n    (rst_n  )  ,
     .          key      (key    )  ,
     .          tx_data  (tx_data)
    );












endmodule

实验结果:

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值