zl程序教程

您现在的位置是:首页 >  后端

当前栏目

重温FPGA开发13

开发 13 FPGA 重温
2023-09-14 09:09:12 时间

串口发送数据任务

使用上一节课设计的串口发送模块,设计一个数据发送器,每10ms以115200的波特率发送一个数据,每次发送的数据比前一个数据大1 (计数器)

在这里插入图片描述

uart_tx_test.v

// 把被测的模块例化进来
module uart_tx_test(
	clk,
	reset,
	uart_tx,	
);
	input clk;
	input reset;
	output uart_tx;
	
	reg send_en;
	reg [7:0]data;

	uart_byte_tx uart_byte_tx(
	.clk(clk),
	.resnet(resnet),
	.data(data),
	.send_en(send_en),
	.baud_set(3'd4),
	.uart_tx(uart_tx),
	.tx_done(tx_done)
	);
	
	reg [18:0] counter;
	always@(posedge clk or negedge reset)
	if(!reset)
		counter <= 0;
	else if(counter == 499999)
		counter <= 0;
	else 
		counter <= counter + 1;

	always@(posedge clk or negedge reset)
	if(!reset)
		counter <= 0;
	else if(counter == 1)
		send <= 1;
	else if(tx_done)
		send_en <= 0;
	
	always@(posedge clk or negedge reset)
	if(!reset)
		data <= 0;
	else if(tx_done)
		data <= data +1'b1;			
	

endmodule

	

uart_tx_test_tb.v

module uart_tx_test_tb
	
	.usrt_tx_test(
		.clk(clk),
		.reset(reset),
		.uart_tx(uart_tx)
	)

	initial clk = 1;
	always #10 clk = ~clk;

	initial begin
		reset = 0;
		#201;
		reset = 1;
		#50000000
	end

endmodule

run 一把试试,发现波形不对

在这里插入图片描述
先找 send en只有一个高电平,看看 send en怎么产生的,counter= 1 的时候 send en拉高,那为什么后面又被拉低了呢?现在怀疑 tx_done的信号?为什么 tx done 一直为高呢?什么时候 tx done拉低呢?所以有个bug存在,没有counter 的case 没有1 的情况。锁以tx done永远不能拉低。改为

在这里插入图片描述

这时候又有bug:data为什么是3 而不是1

在这里插入图片描述
在这里插入图片描述
data在这里为什么连续加了3次
因为检测到tx done 脉冲宽度很重要,应该是一个时钟周期的脉冲,但是现在是3个时钟周期。这时候我们应该确保tx done 每次发送完为一个时钟周期。
让11 只保持一个时钟周期,当dev count产生 bps clk这个脉冲,然后就为11,但后产生 tx done的信号,检测到 tx done 之后,让send en拉低

修改为:
在这里插入图片描述
tx done 单独拿出来赋值

在这里插入图片描述
在这个里面send en完全是主动的视角

假设有个数据采集模块:

修改一下:
在这里插入图片描述
在这里插入图片描述
把send en放到uart_byte_tx 内部来完成,添加一个input接口。
在这里插入图片描述
只要顶层给我一个 send go信号,我就使能send en信号
内部的代码:
在这里插入图片描述
data在直连过来的时候,会不会一直不变?如果在发生的过程中串口的数据忽然变了,一旦外部发送过来,我就立马存下来。内部定义一个寄存器来保存data,每次只要send go的时候 rdata = data:
在这里插入图片描述

在这里插入图片描述

最后 板级验证!

在这里插入图片描述