FPGA学习——UART串口模块
1 `timescale 1ns / 1ps 2 3 /****************************************************************************** 4 * 5 * Module : rx_module
1 `timescale 1ns / 1ps 2 ////////////////////////////////////////////////////////////////////////////////// 3 // Company: 4 // Engineer: 5 // 6 // Create Date: 17:36:30 03/27/2013 7 // Design Name: 8 // Module Name: uart_tx 9 // Project Name: 10 // Target Devices: 11 // Tool versions: 12 // Description: 13 // 14 // Dependencies: 15 // 16 // Revision: 17 // Revision 0.01 - File Created 18 // Additional Comments: 19 // 20 ////////////////////////////////////////////////////////////////////////////////// 21 22 module tx_module( 23 input clk16x, /* transmit clock,16×115200 */ 24 input rst_n, /* glabol reset signal */ 25 input TransEn, /* transmit enable */ 26 input [7:0] DataToTrans, /* Data prepared for transmitting */ 27 28 output reg BufFull, /* Data buffer is full */ 29 output reg tx /* serial data out */ 30 ); 31 32 /* capture the rising edge of TransEn */ 33 reg TransEn_r; 34 wire pos_tri; 35 always@(posedge clk16x or negedge rst_n) 36 begin 37 if(!rst_n) 38 TransEn_r <= 1'b0; 39 else 40 TransEn_r <= TransEn; 41 end 42 assign pos_tri = ~TransEn_r & TransEn; 43 44 /* 45 * when the rising edge of DataEn comes up, load the Data to buffer 46 */ 47 reg [7:0] ShiftReg; 48 always@(posedge pos_tri or negedge rst_n) 49 begin 50 if(!rst_n) 51 ShiftReg <= 8'b0; 52 else 53 ShiftReg <= DataToTrans; 54 end 55 //---------------------------------------------- 56 /* counter control */ 57 reg cnt_en; 58 always@(posedge clk16x or negedge rst_n) 59 begin 60 if(!rst_n) 61 begin 62 cnt_en <= 1'b0; 63 BufFull <= 1'b0; 64 end 65 else if(pos_tri==1'b1) 66 begin 67 cnt_en <=1'b1; 68 BufFull <=1'b1; 69 end 70 else if(cnt==8'd160) 71 begin 72 cnt_en<=1'b0; 73 BufFull <=1'b0; 74 end 75 end 76 77 //--------------------------------------------- 78 /* counter module */ 79 reg [7:0] cnt; 80 always@(posedge clk16x or negedge rst_n) 81 begin 82 if(!rst_n) 83 cnt<=8'd0; 84 else if(cnt_en) 85 cnt<=cnt+1'b1; 86 else 87 cnt<=8'd0; 88 end 89 90 //--------------------------------------------- 91 /* transmit module */ 92 93 always@(posedge clk16x or negedge rst_n) 94 begin 95 if(!rst_n) 96 begin 97 tx <= 1'b1; 98 end 99 else if(cnt_en) 100 case(cnt) 101 'd0 : tx <= 1'b0; 102 'd16 : tx <= ShiftReg[0]; 103 'd32 : tx <= ShiftReg[1]; 104 'd48 : tx <= ShiftReg[2]; 105 'd64 : tx <= ShiftReg[3]; 106 'd80 : tx <= ShiftReg[4]; 107 'd96 : tx <= ShiftReg[5]; 108 'd112 : tx <= ShiftReg[6]; 109 'd128 : tx <= ShiftReg[7]; 110 'd144 : tx <= 1'b1; 111 endcase 112 else 113 tx <= 1'b1; 114 end 115 116 117 endmodule
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 `timescale 1ns / 1ps 2 3 //////////////////////////////////////////////////////////////////////////////// 4 // Company: 5 // Engineer: 6 // 7 // Create Date: 19:29:39 03/27/2013 8 // Design Name: tx_module 9 // Module Name: E:/my_project/Xilinx/ad_lvds/UART/tb_uarttx.v 10 // Project Name: UART 11 // Target Device: 12 // Tool versions: 13 // Description: 14 // 15 // Verilog Test Fixture created by ISE for module: tx_module 16 // 17 // Dependencies: 18 // 19 // Revision: 20 // Revision 0.01 - File Created 21 // Additional Comments: 22 // 23 //////////////////////////////////////////////////////////////////////////////// 24 25 module tb_uart; 26 27 // Inputs 28 reg clk16x; 29 reg rst_n; 30 reg TransEn; 31 reg [7:0] DataToTrans; 32 33 // Outputs 34 wire BufFull; 35 wire tx; 36 wire [7:0] rx_DataReceived; 37 wire rx_dataReady; 38 // Instantiate the Unit Under Test (UUT) 39 tx_module uut ( 40 .clk16x(clk16x), 41 .rst_n(rst_n), 42 .TransEn(TransEn), 43 .DataToTrans(DataToTrans), 44 .BufFull(BufFull), 45 .tx(tx) 46 ); 47 rx_module rx_uut( 48 .GClk(clk16x), /* system topest clock */ 49 .clk16x(clk16x), /* sample clock,16×115200 */ 50 .rst_n(rst_n), /* glabol reset signal */ 51 .rx(tx), /* serial data in */ 52 .DataReady(rx_dataReady), /* a complete byte has been received */ 53 .DataReceived(rx_DataReceived) /* Bytes received */ 54 ); 55 always #5 clk16x = ~clk16x; 56 initial begin 57 // Initialize Inputs 58 clk16x = 0; 59 rst_n =0; 60 TransEn = 0; 61 DataToTrans = 0; 62 // Wait 100 ns for global reset to finish 63 #100; 64 rst_n = 1; 65 TransEn = 1; 66 DataToTrans = 8'b0000_1111; 67 #5000; 68 TransEn = 0; 69 #160; 70 TransEn = 1; 71 DataToTrans = 8'b1111_0000; 72 #5000; 73 $stop; 74 end 75 76 endmodule
6 * File Name : rx_module.v 7 * Author : JC_Wang 8 * Version : 1.0 9 * Date : 2012/12/5 10 * Description : UART接收模块 11 * 12 * 13 ********************************************************************************/ 14 15 module rx_module( 16 input GClk, /* system topest clock */ 17 input clk16x, /* sample clock,16×115200 */ 18 input rst_n, /* glabol reset signal */ 19 input rx, /* serial data in */ 20 output reg DataReady, /* a complete byte has been received */ 21 output reg[7:0] DataReceived /* Bytes received */ 22 ); 23 24 25 /* 捕获rx的下降沿,即起始信号 */ 26 reg trigger_r0; 27 wire neg_tri; 28 always@(posedge GClk or negedge rst_n) /*下降沿使用全局时钟来捕获的,其实用clk16x来捕获也可以*/ 29 begin 30 if(!rst_n) 31 begin 32 trigger_r0<=1'b0; 33 end 34 else 35 begin 36 trigger_r0<=rx; 37 end 38 end 39 40 assign neg_tri = trigger_r0 & ~rx; 41 42 //---------------------------------------------- 43 /* counter control */ 44 reg cnt_en; 45 always@(posedge GClk or negedge rst_n) 46 begin 47 if(!rst_n) 48 cnt_en<=1'b0; 49 else if(neg_tri==1'b1) /*如果捕获到下降沿,则开始计数*/ 50 cnt_en<=1'b1; 51 else if(cnt==8'd152) 52 cnt_en<=1'b0; 53 54 end 55 //--------------------------------------------- 56 /* counter module ,对采样时钟进行计数 */ 57 reg [7:0] cnt; 58 always@(posedge clk16x or negedge rst_n) 59 begin 60 if(!rst_n) 61 cnt<=8'd0; 62 else if(cnt_en) 63 cnt<=cnt+1'b1; 64 else 65 cnt<=8'd0; 66 67 end 68 //--------------------------------------------- 69 /* receive module */ 70 reg StopBit_r; 71 always@(posedge clk16x or negedge rst_n) 72 begin 73 if(!rst_n) 74 begin 75 DataReceived<=8'b0; 76 end 77 else if(cnt_en) 78 case(cnt) 79 8'd24: DataReceived[0] <= rx; /*在各个采样时刻,读取接收到的数据*/ 80 8'd40: DataReceived[1] <= rx; 81 8'd56: DataReceived[2] <= rx; 82 8'd72: DataReceived[3] <= rx; 83 8'd88: DataReceived[4] <= rx; 84 8'd104: DataReceived[5] <= rx; 85 8'd120: DataReceived[6] <= rx; 86 8'd136: DataReceived[7] <= rx; 87 88 endcase 89 90 end 91 92 always@(posedge clk16x or negedge rst_n) 93 begin 94 if(!rst_n) 95 DataReady<=1'b0; 96 else if (cnt==8'd152) 97 DataReady<=1'b1; //接收到停止位后,给出数据准备好标志位 98 else 99 DataReady<=1'b0; 100 end 101 102 endmodule