SDRAM小项目(1)

发布时间:2023年12月23日

记录写SDRAM项目过程中出现的问题

UART接收模块的代码编写及仿真验证(uart_rx)

? ? ? ? 输入信号:系统时钟,复位信号(低电平有效),输入数据(串行)

? ? ? ? 输出信号:串转并输出数据(8位),并行输出后拉高信号

? ? ? ? 中间变量:串行输入数据延时三拍(延时三拍为了信号更加稳定,防止亚稳态?延迟两拍送入串行数据,延时三拍获得接收信号下降沿),接收标志信号(接收数据时拉高)波特计数(当计数到中间值时将数据读取,此时信号最稳定),比特计数(记录8个比特为一个寄存器)

????????

`define SIM

module uart(
		input sclk,
		input srst,
		input rs232_rx,
		output reg [7:0] rx_data,
		output reg po_flag
		);
		
//****************************************************
//define parameter and internal signals
//****************************************************

`ifndef SIM
localparam baud_end = 5207;
`else
localparam baud_end = 56;
`endif

localparam baud_m = baud_end /2 -1;
localparam bit_end = 8;

reg				rx_r1;
reg				rx_r2;
reg				rx_r3;
reg				rx_flag;
reg		[12:0]	baud_cnt;  //5208
reg				bit_flag;
reg		[3:0]	bit_cnt;		
wire			rx_neg;

//====================================================
//     main code
//====================================================
assign rx_neg = ~rx_r2 & rx_r3;

always @(posedge sclk) begin
	rx_r1 <= rs232_rx;
	rx_r2 <= rx_r1;
	rx_r3 <= rx_r2;
end

always@(posedge sclk or negedge srst) begin
	if(srst == 1'b0)
			rx_flag <= 1'b0;
	else if(rx_neg == 1'b1)
			rx_flag <= 1'b1;
	else if(baud_cnt == baud_end && bit_end == 'd0)
			rx_flag <= 1'b0;                          //else
end

always@(posedge sclk or negedge srst) begin           // else if是有优先级的
	if(srst == 1'b0)
			baud_cnt <= 'd0;
	else if(baud_cnt == baud_end)
			baud_cnt <= 'd0;
	else if (rx_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 <= 1'b0;
	else if(baud_cnt == baud_m)
			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_flag == 1'b1 && bit_cnt == bit_end)
			bit_cnt <= 'd0;
		else if(bit_flag == 1'b1)
			bit_cnt <= bit_cnt + 1'b1;
end

always@(posedge sclk or negedge srst) begin
		if(srst == 1'b0)
			rx_data <= 'd0;
		else if(bit_flag == 1'b1  &&	bit_cnt >= 'd1)
			rx_data <= {rx_r2 , rx_data[7:1]};  
end

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

测试代码:

for语句一般不用在功能代码中,这样会综合出复杂的电路

注意串行数据循环传输(data[ ])时要有延时

问题1:readmemh函数传输时候一开始出现x信号,是因为写的相对路径(./data.txt),而仿真时候的工作路径与文件保存的位置不一样,改成了绝对路径。

问题2:波形仿真没有变化,通过查看波形图发现bit_cnt信号定义写错(baud_cnt写成bit_cnt)

问题3:仿真出来的数据只有00和55,后面的数据不一致(未解决),但是其他信号的波形图与视频上的一致。

收获1:串行数据的传递代码示例(寻找更好地写法)

收获2:task函数格式,readmemh函数格式(并不深入)

收获3:通过仿真波形寻找自己代码中问题(解决了data数据无法传输的问题,通过信号没有变化发现了代码中的bit_cnt和baud_cnt写错)

`timescale 1ns/1ns

module tb_uart_rx;

reg		sclk;
reg		srst;
reg		rs232;

wire	po_flag;
wire	[7:0]	rx_data;

//外部txt文件数据写入存储器
reg		[7:0]	mem[3:0];

initial begin
		sclk <= 1;
		srst <= 0;
		rs232 <= 1;
		#100
		srst <= 1;
		#100
		tx_byte();
end


always #5 sclk = ~sclk;		//10ns

initial $readmemh("D:/tx_data.txt", mem);

task	tx_byte();
		integer i ;
		for(i=0;i<4;i=i+1)begin
		tx_bit(mem[i]);
		end

endtask



task tx_bit(								//for循环最好只在仿真时候写,如果写功能语句则会综合出复杂的电路
			input	[7:0]	data
			);
		integer i;
		for(i=0;i<10;i=i+1)begin
			case(i)
			0:	rs232	<=	1'b0;		//起始位
			1:	rs232	<=	data[0];
			2:	rs232	<=	data[1];
			3:	rs232	<=	data[2];
			4:	rs232	<=	data[3];
			5:	rs232	<=	data[4];
			6:	rs232	<=	data[5];
			7:	rs232	<=	data[6];
			8:	rs232	<=	data[7];
			9:	rs232	<=	1'b1;		//停止位
			endcase
			#560;
		end

endtask

uart		uart_inst(
		.sclk			(sclk),
		.srst			(srst),
		.rs232_rx		(rs232),
		.rx_data		(rx_data),
		.po_flag		(po_flag)
		);


endmodule

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