一、实验要求
将生成好的voe文件里的数据使用rom读取出来,采用串口工具发送给电脑(当按键来临时)。
二、程序设计
按键消抖模块:
`timescale 1ns / 1ps
module key_debounce(input sys_clk ,input rst_n ,input key ,output key_flag );
// parameter delay = 100_000_0 ; //20msparameter delay = 100;// 测试用reg[19:0] cnt ;always@(posedge sys_clk )if(!rst_n)cnt <= 0 ;else if ( key == 0 )beginif ( cnt == delay -1 )cnt <= cnt ;else cnt <= cnt +1 ;endelsecnt <= 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_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) tx_data <= 0 ;else if ( tx_flag == 1 )beginif ( 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 ;elsetx_data <= tx_data ; endelsetx_data <= 1 ;///tx_done always@(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
顶层(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 是因为第一个数据要输出,地址要+1addra <= addra +1 ;elseaddra <= 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 ; elseena <= 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 ;elsetx_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 beginsys_clk = 0 ;rst_n = 0 ;key = 1 ;#10 rst_n = 1 ;#1000key = 0 ;endalways #1 sys_clk = ~sys_clk ; rom rom_1(. sys_clk (sys_clk) ,. rst_n (rst_n ) ,. key (key ) ,. tx_data (tx_data));endmodule
实验结果: