SDRAM小项目——uart发送模块

发布时间:2023年12月28日

数据的输入:

? ? ? ? 数据的输入是uart接收模块的输出:串—并—串(接收到的外部的串行数据进入内部寄存器转化为并行数据,再由内部寄存器读出,输出表现为串行数据),接收到的输入信号为tx_flag(po_trig)和tx_data[7:0]。

内部的中间变量:

? ? ? ? tx_data_reg:为寄存器存储输入并行数据

? ? ? ? tx_flag:当开始发送数据的时候为高,停止发送数据时候为低

? ? ? ? baud_cnt:波特计数器,发送一个波特所需要的时钟周期,当计数器记满之后采样,拉高bit_flag电平,输出一个数据

? ? ? ? bit_flag:波特计数器记满之后拉高一个时钟周期,比特计数器加1

? ? ? ? bit_cnt:记满8比特后拉低tx_flag;此时不再发送数据(当第一个bit_flag来的时候发送起始位)计数0-8

数据的输出:

? ? ? ? rs_tx:当bit_flag拉高的时候发送一个数据

时序图:

代码:

`define sim
module uart_tx(	

		input 			sclk,
		input			srst,
		
		output reg		rs232_tx,
		
		input			tx_trig,
		input [7:0]		tx_data
);

//******************************************************
//		degine parameter and internal signal
//******************************************************
`ifndef sim
localparam		baud_end		=		5207;
`else
localparam		baud_end		=		56;
`endif

localparam		bit_end			=		8;

reg 		[7:0]		tx_data_reg;
reg						tx_flag;
reg			[12:0]		baud_cnt;
reg						bit_flag;
reg			[3:0]		bit_cnt;


//========================================================
//				main code
//========================================================

always@(posedge sclk or negedge srst) begin
		if(srst == 1'b0)
				tx_data_reg		<=		'd0;
		else if(tx_trig == 1'b1 && tx_flag == 1'b0)
				tx_data_reg		<=		tx_data;
end


always@(posedge sclk or negedge srst)begin
		if(srst == 1'b0)
				tx_flag		<=		1'b0;
		else if(tx_trig == 1'b1)
				tx_flag		<=		1'b1;
		else if(bit_cnt == bit_end && bit_flag == 1'b1)
				tx_flag		<=		1'b0;
end

always@(posedge sclk or negedge srst)begin
		if(srst == 1'b0)
			baud_cnt	<=	'd0;
		else if(baud_cnt == baud_end)
			baud_cnt	<= 	'd0;
		else if(tx_flag == 1'b1)
			baud_cnt	<=	baud_cnt + 1'b1;
		else 
			baud_cnt	<= 	'd0;
end

always@(posedge sclk or negedge srst)begin
		if(srst == 1'b0)
			bit_flag	<=	'b0;
		else if(baud_cnt == baud_end)
			bit_flag	<=	1'b1;
		else 
			bit_flag	<=	1'b0;
end

always@(posedge sclk or negedge srst)begin
		if(srst == 1'b0)
			bit_cnt <= 'd0;
		else if(bit_cnt == bit_end && bit_flag == 1'b1)
			bit_cnt	<=	'd0;
		else if(bit_flag == 1'b1)
			bit_cnt	<=	bit_cnt + 1'b1;
		//else 
		//	bit_cnt <= 	'd0;
end

always@(posedge sclk or negedge srst) begin
		if(srst == 1'b0)
			rs232_tx	<= 1'b1;
		else if(tx_flag == 1'b1)
			case(bit_cnt)
				0:	rs232_tx	<= 1'b0;
				1:	rs232_tx	<= tx_data_reg[0];
				2:	rs232_tx	<= tx_data_reg[1];
				3:	rs232_tx	<= tx_data_reg[2];
				4:	rs232_tx	<= tx_data_reg[3];
				5:	rs232_tx	<= tx_data_reg[4];
				6:	rs232_tx	<= tx_data_reg[5];
				7:	rs232_tx	<= tx_data_reg[6];
				8:	rs232_tx	<= tx_data_reg[7];
				default:rs232_tx	<=	1'b1;
			endcase
		else 
			rs232_tx	<=	1'b1;
end

endmodule

错误1:`define `ifndef写成`ifdef? 导致仿真的时候baud_cnt计数太大

错误2:srst写成1有效

测试代码:

`timescale 1ns/1ns

module tb_uart_tx;

	reg				sclk;
	reg 			srst;
	reg 			tx_trig;
	reg 	[7:0]	tx_data;
	wire 			rs232_tx;
	
	initial	begin
		sclk	=	1'b1;
		srst	= 	1'b0;
		#100
		srst	=	1'b1;
	end
	
	always
		#5	sclk	=	~sclk;
		
	initial begin
		tx_data	<=	8'b0;
		tx_trig	<=	'b0;
		#200
		tx_trig	<=	'b1;
		tx_data	<=	8'h55;
		#10						//1 clk
		tx_trig	<=	'b0;
	end

uart_tx		uart_tx_inst(	

			.sclk	(sclk)			, 
			.srst	(srst)			,
		
			.rs232_tx	(rs232_tx)	,
		
			.tx_trig		(tx_trig)	,
		 	.tx_data		(tx_data)	
);

endmodule

注意1:if? else语句 else if的适用范围

注意2:当仿真验证通过但是加载到开发板出错以后? 考虑逻辑问题,考虑连线出错没有。

文章来源:https://blog.csdn.net/weixin_49574391/article/details/135272405
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。