FPGA串口

串口接收数据:

`timescale 1ns / 1ns

module MyUart(
	input clk,
	input rst,
	input rx,
	
	output led,
	output start_,
	output [3:0] bitcnt_,
	output reg2_,
	output wire [9:0] buffer_
);

reg reg1;
reg reg2;
reg start;
reg [15:0] baudcnt;
reg [3:0] bitcnt;
reg [9:0] buffer;


always @(posedge clk or negedge rst)	begin
	if(!rst)	begin
		reg1 <= 1'b1;
		reg2 <= 1'b1;		//空闲态
	end
	else begin
		reg1 <= rx;
		reg2 <= reg1;
	end
end

always @(posedge clk or negedge rst)	begin
	if(!rst)	
		start <= 0;
	else if((reg2 == 1'b1) && (reg1 == 1'b0))
		start <= 1'b1;		//检测到下降沿,标志着开始计数
	//如果结束条件一时半会儿不知道怎么写就先放着,先把其他的信号完善好
	else if((bitcnt == 10) && (baudcnt == 5207))	 //接收10个bit
		start <= 0;
	else start <= start;	//防止latch
end

//波特率计数
always @(posedge clk or negedge rst)	begin
		if(!rst)		begin
			baudcnt <= 0;
		end
		else if(start)	begin		//start信号有效时
			if(baudcnt < 5207)
				baudcnt <= baudcnt + 1;
			else 
				baudcnt <= 0;		//溢出清零
		end
		else baudcnt <= 0; 		//start无效时直接清零
end

//比特计数
always@(posedge clk or negedge rst)	begin
	if(!rst)
		bitcnt <= 0;
	else if(start)	begin
		if(baudcnt == 5208/2 - 1)		//判断条件不能写等于0,否则会少接收一位bit
			bitcnt <= bitcnt + 1;
		else bitcnt <= bitcnt;
	end
	else bitcnt <= 0;
end

//接收数据
always @(posedge clk or negedge rst)	begin
	if(!rst)
		buffer <= 0;
	else if(start) begin
		if(baudcnt == 5208 / 2 - 1)	begin //如果start有效并且波特率计数到中间位置时
			case(bitcnt)
				0:	buffer[0] <= reg2;
				1:	buffer[1] <= reg2;
				2:	buffer[2] <= reg2;
				3:	buffer[3] <= reg2;
				4:	buffer[4] <= reg2;
				5:	buffer[5] <= reg2;
				6:	buffer[6] <= reg2;
				7:	buffer[7] <= reg2;
				8:	buffer[8] <= reg2;
				9:	buffer[9] <= reg2;
			endcase 	
		end
	end
end


assign led = buffer[1] && buffer[8];
assign start_ = start;
assign bitcnt_ = bitcnt;
assign reg2_ = reg2;
assign buffer_ = buffer;

endmodule

modelsim:

`timescale 1ns / 1ns

module MyUart_tb;

	// Inputs
	reg clk;
	reg rst;
	reg rx;
	
	// Outputs
	wire led;
	wire start_;
	wire [3:0] bitcnt_;
	wire reg2_;
	wire [9:0] buffer_;
	// Instantiate the Unit Under Test (UUT)
	MyUart uut (
		.clk(clk), 
		.rst(rst), 
		.rx(rx), 
		.led(led), 
		.start_(start_), 
		.bitcnt_(bitcnt_), 
		.reg2_(reg2_),
		.buffer_(buffer_)
	);

	initial begin
		// Initialize Inputs
		clk = 0;
		rst = 0;
		rx = 1;

		// Wait 100 ns for global reset to finish
		#100;
        
		 rst = 1;
		#500000;
		
		rx = 0;		//起始位
		#(5208*20*2);
		rx = 1;
		#(5208*20*2);
		rx = 1;		
		#(5208*20*2);
		rx = 1;
		#(5208*20*2);
		rx = 0;
		#(5208*20*2);
		rx = 1;
		#(5208*20*2);
		rx = 0;
		#(5208*20*2);
		rx = 1;
		#(5208*20*2);
		rx = 1;
		#(5208*20*2);
		rx = 1;				//停止位
		#(5208*20*2);
		  
		// Add stimulus here
		#15_000000;		//15ms
		$stop;
	end
		always #20 clk<=~clk;
endmodule

modelsim:
在这里插入图片描述
接收的基本思路就是:
在数据来的时候检测下降沿,并且拉高start信号,再进行波特率计数,溢出时累加接收到的比特数,在计数到波特率中间位置时去读取rx的值(也就是reg2),将包括起始位、停止位的字节数据存放到buffer里面去。

串口发送:

`timescale 1ns / 1ns

module TX(
	input clk ,
	input rst ,
	output reg tx ,
	
	output wire start_ ,
	output wire [3:0] bitcnt_
);

reg [31:0] cnt;
reg start;
reg [15:0] baudcnt;
reg [3:0] bitcnt;
reg [9:0] buffer = 10'b1_0000_1100_0; //0x0c

assign start_ = start;
assign bitcnt_ = bitcnt;

//1s倒计时
always @(posedge clk or negedge rst)		begin
	if(!rst)	begin
		cnt <= 1'b0;
		end
	else if(cnt < 50_000_000)
		cnt <= cnt + 1;
	else if(cnt == 50_000_000) begin 
		cnt <= 0;	
end
end

//延时
always @(posedge clk or negedge rst)	begin
	if(!rst)
		start <= 1'b0;
	else if(cnt == 5207*10)	
		start <= 1'b0;
	else if(!cnt)
		start <= 1'b1;
end

//波特率计数
always@(posedge clk or negedge rst)	begin
	if(!rst)
		baudcnt <= 0;
	else if(start)	begin
		if(baudcnt < 5207)
			baudcnt <= baudcnt + 1;
		else if(baudcnt == 5207) begin 
			baudcnt <= 0;	
			bitcnt <= bitcnt + 1;
		end
		else if(bitcnt == 10)
			bitcnt <= 0;
	end
	else begin 
			baudcnt <= 0;	
			bitcnt <= 0;
	end
end


always @(posedge clk or negedge rst)	begin
	if(!rst)	
		buffer <= buffer;
	else if(start)	begin
		if((baudcnt == 0) || (baudcnt == 1)) begin
			case(bitcnt)
			0: tx <= buffer[0];
			1: tx <= buffer[1];
			2: tx <= buffer[2];
			3: tx <= buffer[3];
			4: tx <= buffer[4];
			5: tx <= buffer[5];
			6: tx <= buffer[6];
			7: tx <= buffer[7];
			8: tx <= buffer[8];
			9: tx <= buffer[9];
			endcase 
		end
	end
end

endmodule 

完整串口回环测试工程:https://download.csdn.net/download/qq_45955402/87859087

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ho_Yim

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值