FPGA入门实验之串口发送

要求 串口助手功能实现,5个按键,按一次输出1种波特率的信号及他的一半波特率的信号,再按一次输出另一种信号,依次对应。
代码设计

## 分频模块

module frequency( input clk_50m, input rst, output BPS_CLK1,//输出为不同波特率的信号 output BPS_CLK2, output BPS_CLK3, output BPS_CLK4, output BPS_CLK5, output BPS_CLK6, output BPS_CLK7, output BPS_CLK8, output BPS_CLK9, output BPS_CLK10 ); reg [12:0]cnt_bps1=0; reg [12:0]cnt_bps2=0; reg [12:0]cnt_bps3=0; reg [12:0]cnt_bps4=0; reg [12:0]cnt_bps5=0; reg [12:0]cnt_bps6=0; reg [12:0]cnt_bps7=0; always@(posedge clk_50m or posedge rst) if(rst)//复位信号 cnt_bps1<=0; else if(cnt_bps1==13'd5207)// 50_000_000/9600 cnt_bps1<=0; else cnt_bps1<=cnt_bps1+1; always@(posedge clk_50m or posedge rst) if(rst) cnt_bps2<=0; else if(cnt_bps2==13'd2603)//19200 cnt_bps2<=0; else cnt_bps2<=cnt_bps2+1; always@(posedge clk_50m or posedge rst) if(rst) cnt_bps3<=0; else if(cnt_bps3==13'd1301)//38400 cnt_bps3<=0; else cnt_bps3<=cnt_bps3+1; always@(posedge clk_50m or posedge rst) if(rst) cnt_bps4<=0; else if(cnt_bps4==13'd867)//57600 cnt_bps4<=0; else cnt_bps4<=cnt_bps4+1; always@(posedge clk_50m or posedge rst) if(rst) cnt_bps5<=0; else if(cnt_bps5==13'd433) cnt_bps5<=0; else cnt_bps5<=cnt_bps5+1; always@(posedge clk_50m or posedge rst) if(rst) cnt_bps6<=0; else if(cnt_bps6==13'd1301)//115200 cnt_bps6<=0; else cnt_bps6<=cnt_bps6+1; always@(posedge clk_50m or posedge rst) if(rst) cnt_bps7<=0; else if(cnt_bps7==13'd215) cnt_bps7<=0; else cnt_bps7<=cnt_bps7+1; assign BPS_CLK1=(cnt_bps1==13'd2604)?1:0; assign BPS_CLK2=(cnt_bps2==13'd1302)?1:0; assign BPS_CLK3=(cnt_bps3==13'd868)?1:0; assign BPS_CLK4=(cnt_bps4==13'd434)?1:0; assign BPS_CLK5=(cnt_bps5==13'd217)?1:0; assign BPS_CLK6=(cnt_bps2==13'd1302)?1:0; assign BPS_CLK7=(cnt_bps6==13'd651)?1:0; assign BPS_CLK8=(cnt_bps4==13'd434)?1:0; assign BPS_CLK9=(cnt_bps5==13'd217)?1:0; assign BPS_CLK10=(cnt_bps7==13'd018)?1:0; endmodule

七个always语句里面分别产生对应波特率信号的计数。比如要产生9600的就应该是计数(系统时钟50m除以9600)下。
## 按键模块
module key( input clk_50m, input key, input rst, input BPS_CLK1, input BPS_CLK2, input BPS_CLK3, input BPS_CLK4, input BPS_CLK5, input BPS_CLK6, input BPS_CLK7, input BPS_CLK8, input BPS_CLK9, input BPS_CLK10, output reg sent_clk=0, output reg res_clk=0 ); reg [2:0] key_cn=0; always@(posedge clk_50m or posedge rst)//检测按键次数,用于转换输出不同的波特率 if(rst) key_cn<=0; else if(key==1) if(key_cn==4) key_cn<=0; else key_cn<=key_cn+1; always@(posedge clk_50m)//根据按键次数输出不同波特率的信号及它的一半 case(key_cn) 3'd0:begin sent_clk<=BPS_CLK1; res_clk<=BPS_CLK6; end 3'd1:begin sent_clk<=BPS_CLK2; res_clk<=BPS_CLK7; end 3'd2:begin sent_clk<=BPS_CLK3; res_clk<=BPS_CLK8; end 3'd3:begin sent_clk<=BPS_CLK4; res_clk<=BPS_CLK9; end 3'd4:begin sent_clk<=BPS_CLK5; res_clk<=BPS_CLK10; end default:begin sent_clk<=BPS_CLK1; res_clk<=BPS_CLK6; end endcaseendmodule

按键计数,把按键当作使能信号,当按键按下,按键计数器计数,之后case语句判断按键次数,然后赋值输出对应波特率及他的一半;输出为sen_clk与rec_clk。也就是按一次键会产生两种波特率信号。
## 顶层文件
module top( input clk_50m, input key, input rst, output sent_clk, output res_clk ); wire BPS_CLK1,BPS_CLK2,BPS_CLK3,BPS_CLK4,BPS_CLK5,BPS_CLK6,BPS_CLK7,BPS_CLK8,BPS_CLK9,BPS_CLK10; wire BPS1,BPS2,BPS3,BPS4,BPS5,BPS6,BPS7,BPS8,BPS9,BPS10; frequency i1 ( .clk_50m(clk_50m), .rst(rst), .BPS_CLK1(BPS1), .BPS_CLK2(BPS2), .BPS_CLK3(BPS3), .BPS_CLK4(BPS4), .BPS_CLK5(BPS5), .BPS_CLK6(BPS6), .BPS_CLK7(BPS7), .BPS_CLK8(BPS8), .BPS_CLK9(BPS9), .BPS_CLK10(BPS10) ); key i2( .clk_50m(clk_50m), .key(key), .BPS_CLK1(BPS1), .BPS_CLK2(BPS2), .BPS_CLK3(BPS3), .BPS_CLK4(BPS4), .BPS_CLK5(BPS5), .BPS_CLK6(BPS6), .BPS_CLK7(BPS7), .BPS_CLK8(BPS8), .BPS_CLK9(BPS9), .BPS_CLK10(BPS10), .sent_clk(sent_clk), .res_clk(res_clk) ); endmodule

## 仿真文件

module uart_clk; // Inputs reg clk_50m; reg key; reg rst; // Outputs wire sent_clk; wire res_clk; // Instantiate the Unit Under Test (UUT) top uut ( .clk_50m(clk_50m), .key(key), .rst(rst), .sent_clk(sent_clk), .res_clk(res_clk) ); initial begin // Initialize Inputs clk_50m = 0; key = 0; rst = 0; end always #10 clk_50m=!clk_50m; always beginkey<=1; #20; key<=0; #500000; endendmodule

仿真波形 【FPGA入门实验之串口发送】FPGA入门实验之串口发送
文章图片

    推荐阅读