九五656 2021-02-02 14:28 采纳率: 0%
浏览 203
已结题

quartus qsys sdram ip时序问题

一个关于qsys sdram的时序问题,希望各位有经验的大佬给予一些解决方法

将时序进行约束后,其他违规的我都已经改好了
就剩下这一个qsys sdram ip内部的违规我不知道该怎么修改好,
首先我把这个模块里面把我自己认为该改的都改好了,其他模块也优化了大概2k LE出来,但对这个违规并没什么改善

用signaltap ii看读写数据时,写进去数据全为0,但出来同一个地址,数据变化乱跳
时而有数据时而为0,当程序才烧入FPGA时还好,但是跑了一段时间后,现在就严重了

困惑了好久,请各位给出一个解决方案,指出指出代码编写中存在的问问,谢谢大佬

module	qsys_sdram_ctrl
(
	clk							,
	rst_n							,
	sync							,
	sdram_rd_en					,
	rd_done_sig					,
	MOD_HALF						,
	RD_LEN						,
	mod_h							,
	mod_v							,
	mod_l							,
	mod_c							,
	mod_p							,
	mod_g							,
	port0_init					,
	port1_init					,
	port2_init					,
	port3_init					,
	port4_init					,
	port5_init					,
	port6_init					,
	port7_init					,
	port8_init					,
	port9_init					,
	port10_init					,
	port11_init					,
	wr_ram_wrreq				,
	wr_ram_wraddress			,
	sdram_ctrl_readdatavalid,
	bit_dif						,
	bit_select1					,
	bit_select2					,
	frame_init					,
	sdram_datain				,
	sdram_ctrl_chipselect	,
	sdram_ctrl_byteenable_n	,
	sdram_ctrl_address		,
	sdram_ctrl_writedata		,
	sdram_ctrl_read			,
	sdram_ctrl_write			,
	sdram_ctrl_waitrequest	,
	ram_rd_en					,
	ram_rdaddress				,
	sdram_read_en				,
	rd_flag
);

	input									clk					;
	input									rst_n					;
	input									rd_done_sig			;
	input									sdram_rd_en			/* synthesis keep */;
	input									wr_ram_wrreq		/* synthesis keep */;
	input				[ 7:0]			wr_ram_wraddress	;
	input				[ 3:0]			bit_dif				;
	input				[ 3:0]			bit_select1			;
	input				[ 3:0]			bit_select2			;
	input				[31:0]			sdram_datain		;
	input									sdram_ctrl_readdatavalid;
	input									sync					;
	input				[13:0]			MOD_HALF				;
	input				[ 7:0]			RD_LEN				;
	input				[ 5:0]			mod_h					;
	input				[ 8:0]			mod_v					;
	input				[ 4:0]			mod_l					;
	input				[ 3:0]			mod_c					;
	input				[ 6:0]			mod_p					;
	input				[ 6:0]			mod_g					;
	input				[14:0]			port0_init			;
	input				[14:0]			port1_init			;
	input				[14:0]			port2_init			;
	input				[14:0]			port3_init			;
	input				[14:0]			port4_init			;
	input				[14:0]			port5_init			;
	input				[14:0]			port6_init			;
	input				[14:0]			port7_init			;
	input				[14:0]			port8_init			;
	input				[14:0]			port9_init			;
	input				[14:0]			port10_init			;
	input				[14:0]			port11_init			;
	
	output	reg						frame_init			;
	output	reg	[16:0]			ram_rd_en			;
	output	reg	[ 7:0]			ram_rdaddress		;
	output								sdram_ctrl_chipselect;
	output	 	 	[ 3:0]  			sdram_ctrl_byteenable_n;
	output	reg  	[20:0] 			sdram_ctrl_address;
	output 	reg  	[31:0] 			sdram_ctrl_writedata;
	output 	reg         			sdram_ctrl_read;
	output	reg         			sdram_ctrl_write;
	output	reg						rd_flag;
	output	reg						sdram_read_en;
	input				        			sdram_ctrl_waitrequest;

	localparam							EN_READ		=		1'b0	;
	localparam							DIS_READ		=		1'b1	;
	localparam							EN_WRITE		=		1'b0	;
	localparam							DIS_WRITE	=		1'b1	;
	
	localparam							SYNC			=		4'd0	;
	localparam 							INIT 			=		4'd1	;
	localparam							WRITE_INIT	=		4'd2	;
	localparam							WRITE_INIT2	=		4'd3	;
	localparam							WRITE			=		4'd4	;
	localparam							WRITE1		=		4'd5	;
	localparam							WRITE_DONE	=		4'd6	;
	localparam							READ_INIT	=		4'd7	;
	localparam							READ			=		4'd8	;
	localparam							READ_DONE	=		4'd9	;
	
	
	parameter							BIT0_INIT	=		21'd0;
	parameter							BIT1_INIT	=		21'd18432;
	parameter							BIT2_INIT	=		21'd36864;
	parameter							BIT3_INIT	=		21'd55296;
	parameter							BIT4_INIT	=		21'd73728;
	parameter							BIT5_INIT	=		21'd92160;
	parameter							BIT6_INIT	=		21'd110592;
	parameter							BIT7_INIT	=		21'd129024;
	parameter							BIT8_INIT	=		21'd147456;
	parameter							BIT9_INIT	=		21'd165888;
	parameter							BIT10_INIT	=		21'd184320;
	parameter							BIT11_INIT	=		21'd202752;
	parameter							BIT12_INIT	=		21'd221184;
	parameter							BIT13_INIT	=		21'd239616;
	parameter							BIT14_INIT	=		21'd258048;
	parameter							BIT15_INIT	=		21'd276480;
	parameter							MOD_DONE		=		21'd290304;
	parameter							MOD_DONE2	=		21'd585216;
	parameter							BIT_DONE		=		21'd294912;
	parameter							BIT_DONE2	=		21'd589824;
	parameter							BIT_HALF		=		21'd9216;
	parameter							NEXT_DONE	=		BIT_HALF + BIT_DONE;
	
	parameter 							INIT_COUNT	=		9'd10;
	
	reg				[3:0]				current_state				;
	reg				[3:0]				next_state					/* synthesis keep */;
	/////////////////////////////////////////////
	reg				[20:0]			rd_bit_init;
	reg				[20:0]			wr_bit_init;
	reg				[20:0]			write_init;
	reg				[20:0]			rd_rgb_init;
	reg				[ 3:0]			sdram_rd_bit;
	reg									rd_bit_flag;
	reg									sync_f1;
	reg									sync_f2;
	wire									sync_h2l;
	reg									wr_flag_f1;
	reg									wr_flag_f2;
	wire									wr_flag_h2l;
	
	reg									flag;
	reg									rd_en;
	reg									write_en;
	reg									sdram_write_en;
//	reg									sdram_read_en;
//	reg									sdram_rd_init;
	reg				[ 9:0]			counter;
	reg									skip_en;
	reg				[16:0]			ram_rd_en_reg;
	reg				[13:0]			sdram_wraddress;
	reg				[14:0]			sdram_rdaddress;
	reg				[ 4:0]			cnt;
	reg									read_sig;
	reg				[10:0]			write_cnt;
	reg				[13:0]			read_cnt;
	reg									rd_done;
	reg									wr_done;
	reg				[ 5:0]			cnt_h;
	reg				[ 8:0]			cnt_v;
	reg				[ 4:0]			cnt_l;
	reg				[ 3:0]			cnt_c;
	reg				[ 6:0]			cnt_p;
	reg				[ 6:0]			cnt_g;
	reg				[14:0]			port0_addr;
	reg				[14:0]			port1_addr;
	reg				[14:0]			port2_addr;
	reg				[14:0]			port3_addr;
	reg				[14:0]			port4_addr;
	reg				[14:0]			port5_addr;
	reg				[14:0]			port6_addr;
	reg				[14:0]			port7_addr;
	reg				[14:0]			port8_addr;
	reg				[14:0]			port9_addr;
	reg				[14:0]			port10_addr;
	reg				[14:0]			port11_addr;
	
	assign	sdram_ctrl_chipselect = 1'b1;
	assign	sdram_ctrl_byteenable_n = 4'b0;
	assign	sync_h2l			=	!sync_f1 & sync_f2;
	assign	wr_flag_h2l		=	!wr_flag_f1 & wr_flag_f2;
	//帧同步信号下降沿检测
	always @(posedge clk) begin
		sync_f1										<=		sync;
		sync_f2										<=		sync_f1;
	end
	//写标志下降沿检测
	always @(posedge clk) begin
		wr_flag_f1									<=		wr_flag;
		wr_flag_f2									<=		wr_flag_f1;
	end
	//写地址初地址,16个bit数据分16个区域存储
	always @(posedge clk) begin
		case(ram_rd_en)
			17'd2			:	wr_bit_init			<=		BIT0_INIT;
			17'd4			:	wr_bit_init			<=		BIT1_INIT;
			17'd8			:	wr_bit_init			<=		BIT2_INIT;
			17'd16		:	wr_bit_init			<=		BIT3_INIT;
			17'd32		:	wr_bit_init			<=		BIT4_INIT;
			17'd64		:	wr_bit_init			<=		BIT5_INIT;
			17'd128		:	wr_bit_init			<=		BIT6_INIT;
			17'd256		:	wr_bit_init			<=		BIT7_INIT;
			17'd512		:	wr_bit_init			<=		BIT8_INIT;
			17'd1024		:	wr_bit_init			<=		BIT9_INIT;
			17'd2048		:	wr_bit_init			<=		BIT10_INIT;
			17'd4096		:	wr_bit_init			<=		BIT11_INIT;
			17'd8192		:	wr_bit_init			<=		BIT12_INIT;
			17'd16384	:	wr_bit_init			<=		BIT13_INIT;
			17'd32768	:	wr_bit_init			<=		BIT14_INIT;
			17'd65536	:	wr_bit_init			<=		BIT15_INIT;
			default		:	wr_bit_init			<=		BIT0_INIT;
		endcase
	end
	//读地址初地址,根据当前哪个bit的数据,便从哪个初地址开始读
	always @(posedge clk) begin
		case(sdram_rd_bit)
			4'd15			:	rd_bit_init			<=		BIT0_INIT;
			4'd14			:	rd_bit_init			<=		BIT1_INIT;
			4'd13			:	rd_bit_init			<=		BIT2_INIT;
			4'd12			:	rd_bit_init			<=		BIT3_INIT;
			4'd11			:	rd_bit_init			<=		BIT4_INIT;
			4'd10			:	rd_bit_init			<=		BIT5_INIT;
			4'd9			:	rd_bit_init			<=		BIT6_INIT;
			4'd8			:	rd_bit_init			<=		BIT7_INIT;
			4'd7			:	rd_bit_init			<=		BIT8_INIT;
			4'd6			:	rd_bit_init			<=		BIT9_INIT;
			4'd5			:	rd_bit_init			<=		BIT10_INIT;
			4'd4			:	rd_bit_init			<=		BIT11_INIT;
			4'd3			:	rd_bit_init			<=		BIT12_INIT;
			4'd2			:	rd_bit_init			<=		BIT13_INIT;
			4'd1			:	rd_bit_init			<=		BIT14_INIT;
			4'd0			:	rd_bit_init			<=		BIT15_INIT;
			default		:	rd_bit_init			<=		BIT0_INIT;
		endcase
	end
	//写标志,每一个bit分两组数据,标志位为0存第一组数据,反之则存第二组数据
	reg							wr_flag;
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			wr_flag									<=		1'b0;
		else if(sync)
			wr_flag									<=		1'b0;
		else if(sdram_wraddress == MOD_HALF)		//第一组数据存满,标志位变化开始存第二组
			wr_flag									<=		~wr_flag;
		else
			wr_flag									<=		wr_flag;
	end
	//写地址选择寄存器
	reg			[ 3:0]		wr_select;
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			wr_select								<=		4'b0;
		else if(sync)
			wr_select								<=		4'b0;
		else begin
			if(wr_flag_h2l)
				wr_select							<=		wr_select + 1'b1;
			else
				wr_select							<=		wr_select;
		end
	end
	//根据写选择寄存器,对当前bit当前数据该写入的初地址进行选择
	reg			[20:0]		wraddress_init;
	always @(posedge clk) begin
		case(wr_select)
			4'd0 : wraddress_init				<=		21'b0;
			4'd1 : wraddress_init				<=		21'd1152;
			4'd2 : wraddress_init				<=		21'd2304;
			4'd3 : wraddress_init				<=		21'd3456;
			4'd4 : wraddress_init				<=		21'd4608;
			4'd5 : wraddress_init				<=		21'd5760;
			4'd6 : wraddress_init				<=		21'd6912;
			4'd7 : wraddress_init				<=		21'd8064;
			4'd8 : wraddress_init				<=		21'd9216;
			4'd9 : wraddress_init				<=		21'd10368;
			4'd10 : wraddress_init				<=		21'd11520;
			4'd11 : wraddress_init				<=		21'd12672;
			default : wraddress_init			<=		21'b0;
		endcase
	end
	//前级ram全部写完标志信号
	reg							ram_rd_en_f1	;
	reg							ram_rd_en_f2	;
	wire							ram_rd_en_h2l	;
	assign	ram_rd_en_h2l	=	!ram_rd_en_f1 & ram_rd_en_f2;
	always @(posedge clk) begin
		ram_rd_en_f1								<=		ram_rd_en[16];
		ram_rd_en_f2								<=		ram_rd_en_f1;
	end
	//sdram当前读完毕标志信号
	reg							read_f1;
	reg							read_f2;
	wire							read_sig_h2l;
	assign	read_sig_h2l	=	!read_f1 & read_f2;
	always @(posedge clk) begin
		read_f1										<=		read_sig;
		read_f2										<=		read_f1;
	end
	//乒乓读sdram信号
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			rd_done									<=		1'b0;
		else if(rd_done_sig)						//当前sdram全部读完,乒乓下一帧读取
			rd_done									<=		~rd_done;
		else
			rd_done									<=		rd_done;
	end
	//乒乓写sdram信号
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			wr_done									<=		1'b0;
		else begin
			case(next_state)
				WRITE_DONE	:	begin
					if(sdram_ctrl_address == MOD_DONE2 - 1'b1)
						wr_done						<=		1'b0;
					else if(sdram_ctrl_address == MOD_DONE - 1'b1)
						wr_done						<=		1'b1;
					else
						wr_done						<=		wr_done;
				end
				default		:	wr_done			<=		wr_done;
			endcase
		end
	end
	//sdram写使能
	always @(posedge clk or negedge rst_n) begin	
		if(!rst_n)
			write_en									<=		1'b0;
		else if(sync)
			write_en									<=		1'b0;
		else begin
			if(wr_ram_wrreq && (wr_ram_wraddress == 8'd128 || wr_ram_wraddress == 8'd255))	//当前级ram乒乓写满一半
				write_en								<=		1'b1;													//开始读前级ram,并将读出数据存入sdram当中
			else if(ram_rd_en_h2l && (ram_rdaddress == 8'd128 || ram_rdaddress == 8'd0))		//当前级ram读完一半后,写使能关闭
				write_en								<=		1'b0;
			else
				write_en								<=		write_en;
		end
	end
	//sdram实际写使能,当前如果有读信号读,则实际写使能清零,实现读优先
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			sdram_write_en							<=		1'b0;
		else if(sync)
			sdram_write_en							<=		1'b0;
		else begin
			if(sdram_read_en && rd_en)
				sdram_write_en						<=		1'b0;
			else
				sdram_write_en						<=		write_en;
		end
	end
	//最后两个ram在读时候,不进行sdram读操作,防止前级ram写数据溢出
	always @(posedge clk) begin
		if(ram_rd_en[15] || ram_rd_en[14])
			rd_en										<=		1'b0;
		else
			rd_en										<=		1'b1;
	end
	//sdram读使能
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			sdram_read_en							<=		1'b0;
		else if(sync)
			sdram_read_en							<=		1'b0;
		else begin
			if(sdram_rd_en)						//读信号到,读使能置位
				sdram_read_en						<=		1'b1;
			else if(read_sig_h2l)				//读完成信号到,读使能清零
				sdram_read_en						<=		1'b0;
			else
				sdram_read_en						<=		sdram_read_en;
		end
	end
	//三段式状态机
	always @(posedge clk or negedge rst_n)	begin
		if(!rst_n)
			current_state							<=		SYNC;
		else if(sync)
			current_state							<=		SYNC;
		else
			current_state							<=		next_state;
	end
	//////////////////////////////////////////////////////
	always @(*)	begin
		next_state 									=		INIT;
		case(current_state)
			SYNC			:		begin
				if(sync_h2l)
					next_state						=		INIT;
				else
					next_state						=		SYNC;
			end
			INIT			:		begin
				if(sdram_write_en)
				if(sdram_read_en && rd_en)
					next_state						=		READ_INIT;
				else if(sdram_write_en)
					next_state						=		WRITE_INIT;
				else
					next_state						=		INIT;
			end
			READ_INIT	:		begin
				if(skip_en)
					next_state						=		READ;
				else
					next_state						=		READ_INIT;
			end
			READ			:		begin
				if(skip_en)
					next_state						=		READ_DONE;
				else
					next_state						=		READ;
			end
			READ_DONE	:		begin
				if(skip_en)
					next_state						=		INIT;
				else
					next_state						=		READ_DONE;
			end
			WRITE_INIT	:		begin
				if(skip_en)
					next_state						=		WRITE_INIT2;
				else
					next_state						=		WRITE_INIT;
			end
			WRITE_INIT2	:		begin
				if(skip_en)
					next_state						=		WRITE;
				else
					next_state						=		WRITE_INIT2;
			end
			WRITE			:		begin
				if(skip_en)
					next_state						=		WRITE1;
				else
					next_state						=		WRITE;
			end
			WRITE1		:		begin
				if(skip_en)
					next_state						=		WRITE_DONE;
				else
					next_state						=		WRITE1;
			end
			WRITE_DONE	:		begin
				if(skip_en)
					next_state						=		INIT;
				else
					next_state						=		WRITE_DONE;
			end
			default	:	next_state				=		SYNC;
		endcase
	end
	//状态跳转
	always @(posedge clk) begin
		skip_en										<=		1'b0;
		case(next_state)
			READ_INIT		:		begin
				if(counter == 10'd2)													//空两个时钟出来,给初始化端口0的地址使用
					skip_en							<=		1'b1;
			end
			READ				:		begin
				if(counter == RD_LEN - 1'b1 && !sdram_ctrl_waitrequest)	//当计数满且sdram不是忙碌状态
					skip_en							<=		1'b1;
			end
			READ_DONE		:		begin
				if(counter == INIT_COUNT)											//计满跳转,保证sdram刷新时间
					skip_en							<=		1'b1;
			end
			WRITE_INIT		:	skip_en			<=		1'b1;						//打一拍
			WRITE_INIT2		:		begin
				if(counter == 10'd1)
					skip_en							<=		1'b1;
			end
			WRITE				:		begin
				if(!sdram_ctrl_waitrequest && counter == 10'd126)			//写计满且sdram不是忙碌状态
					skip_en							<=		1'b1;
			end
			WRITE1			:		begin
				if(!sdram_ctrl_waitrequest)										//非忙碌状态
					skip_en							<=		1'b1;
			end
			WRITE_DONE		:		begin
				if(counter == INIT_COUNT)											//计满跳转,保证sdram刷新时间
					skip_en							<=		1'b1;
			end
			default	:	skip_en					<=		1'b0;
		endcase
	end
	//计数跳转
	always @(posedge clk) begin
		case(next_state)
			READ_INIT		:		begin
				if(counter == 10'd2)
					counter							<=		10'b0;
				else
					counter							<=		counter + 1'b1;
			end
			READ				:		begin
				if(counter == RD_LEN - 1'b1 && !sdram_ctrl_waitrequest)
					counter							<=		10'b0;
				else if(!sdram_ctrl_waitrequest)
					counter							<= 	counter + 1'b1;
			end
			READ_DONE		:		begin
				if(counter == INIT_COUNT)
					counter							<=		10'b0;
				else
					counter							<=		counter + 1'b1;
			end
			WRITE_INIT2		:		begin
				if(counter == 10'd1)
					counter							<=		10'b0;
				else
					counter							<=		counter + 1'b1;
			end
			WRITE				:		begin
				if(!sdram_ctrl_waitrequest && counter == 10'd126)
					counter							<=		8'b0;
				else if(!sdram_ctrl_waitrequest)
					counter							<= 	counter + 1'b1;
			end
			WRITE_DONE		:		begin
				if(counter == INIT_COUNT)
					counter							<=		10'd0;
				else
					counter							<=		counter + 1'b1;
			end
		endcase
	end
	//sdram读使能控制,读长度由RD_LEN控制
	always @(posedge clk) begin
		case(next_state)
			READ_INIT		:		begin
				if(counter == 10'd2)
					sdram_ctrl_read				<=		EN_READ;
				else
					sdram_ctrl_read				<=		DIS_READ;
			end
			READ				:		begin
				sdram_ctrl_read					<=		EN_READ;
				if(counter == RD_LEN - 1'b1 && !sdram_ctrl_waitrequest)
					sdram_ctrl_read				<=		DIS_READ;
			end
			default	:	sdram_ctrl_read		<=		DIS_READ;
		endcase
	end
	//sdram写使能,写长度为128个数据
	always @(posedge clk) begin
		case(next_state)
			WRITE , WRITE1	:
				sdram_ctrl_write					<=		EN_WRITE;
			default			:
				sdram_ctrl_write					<=		DIS_WRITE;
		endcase
	end
	//当前写sdram初地址
	always @(posedge clk)
		write_init									<=		wraddress_init + wr_bit_init;
	//sdram读写地址控制
	always @(posedge clk) begin
		case(next_state)
			SYNC				:
				sdram_ctrl_address				<=		21'b0;
			READ_INIT		:		begin
				if(!sdram_ctrl_waitrequest) begin
					if(!rd_done) begin
						if(rd_flag)
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress + BIT_HALF;
						else
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress;
						
					end
					else begin
						if(rd_flag)
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress + NEXT_DONE;
						else
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress + BIT_DONE;
					end
				end
				else
					sdram_ctrl_address			<=		sdram_ctrl_address;
			end
			READ				:		begin
				if(!sdram_ctrl_waitrequest) begin
					if(!rd_done) begin
						if(rd_flag)
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress + BIT_HALF;
						else
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress;
					end
					else begin
						if(rd_flag)
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress + NEXT_DONE;
						else
							sdram_ctrl_address	<=		rd_bit_init + sdram_rdaddress + BIT_DONE;
					end
				end
			end
			WRITE				:		begin
				if(!sdram_ctrl_waitrequest) begin
					if(wr_done) begin
						if(wr_flag)
							sdram_ctrl_address	<=		sdram_wraddress + NEXT_DONE;
						else
							sdram_ctrl_address	<=		sdram_wraddress + BIT_DONE;
					end
					else begin
						if(wr_flag)
							sdram_ctrl_address	<=		sdram_wraddress + BIT_HALF;
						else
							sdram_ctrl_address	<=		sdram_wraddress;
					end
				end
				else
					sdram_ctrl_address			<=		sdram_ctrl_address;
			end
			WRITE1			:		begin
				if(!sdram_ctrl_waitrequest) begin
					if(wr_done) begin
						if(wr_flag)
							sdram_ctrl_address	<=		sdram_wraddress + NEXT_DONE;
						else
							sdram_ctrl_address	<=		sdram_wraddress + BIT_DONE;
					end
					else begin
						if(wr_flag)
							sdram_ctrl_address	<=		sdram_wraddress + BIT_HALF;
						else
							sdram_ctrl_address	<=		sdram_wraddress;
					end
				end
				else
					sdram_ctrl_address			<=		sdram_ctrl_address;
			end
			default	:	sdram_ctrl_address	<=		sdram_ctrl_address;
		endcase
	end
	//sdram写地址寄存器,当前级ram 16个都读取完毕,则开始存到下一轮地址当中
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	sdram_wraddress	<=		14'b0;
			WRITE			:		begin
				if(!sdram_ctrl_waitrequest)
					sdram_wraddress				<=		sdram_wraddress + 1'b1;
			end
			WRITE1		:		begin
				if(!sdram_ctrl_waitrequest) begin
					if(ram_rd_en[16])
						sdram_wraddress			<=		sdram_wraddress + 1'b1;
					else
						sdram_wraddress			<=		sdram_wraddress - 14'd127;
				end
			end
			WRITE_DONE	:		begin
				if(sdram_wraddress == MOD_HALF)
					sdram_wraddress				<=		14'b0;
				else
					sdram_wraddress				<=		sdram_wraddress;
			end
			default	:	sdram_wraddress		<=		sdram_wraddress;
		endcase
	end
	//写sdram数据,非忙碌则正常存,否则便保存数据不变
	always @(posedge clk) begin
		if(!sdram_ctrl_waitrequest)
			sdram_ctrl_writedata					<=		sdram_datain;
		else
			sdram_ctrl_writedata					<=		sdram_ctrl_writedata;
	end
	//前级sdram读使能信号,没读完128个数据便跳转至下一ram进行使能读取
	always @(posedge clk) begin
		case(next_state)
			SYNC				:	ram_rd_en		<=		17'b1;
			WRITE_INIT		:	ram_rd_en		<=		{ram_rd_en[15:0] , ram_rd_en[16]};
			WRITE_DONE		:		begin
				if(ram_rd_en[16])
					ram_rd_en						<=		17'd1;
				else
					ram_rd_en						<=		ram_rd_en;
			end
			default	:	ram_rd_en				<=		ram_rd_en;
		endcase
	end
	//读前级ram地址
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	ram_rdaddress		<=		8'd0;
			WRITE_INIT2	:	ram_rdaddress		<=		ram_rdaddress + 1'b1;
			WRITE			:		begin
				if(!sdram_ctrl_waitrequest && counter < 10'd125)
					ram_rdaddress					<=		ram_rdaddress + 1'b1;
				if(!sdram_ctrl_waitrequest && counter == 10'd125) begin
					if(ram_rd_en[16])
						ram_rdaddress				<=		ram_rdaddress + 1'b1;
					else
						ram_rdaddress				<=		ram_rdaddress - 8'd127;
				end
			end
			default : ram_rdaddress				<=		ram_rdaddress;
		endcase
	end
	//sdram当前读bit控制
	always @(posedge clk) begin
		if(sync)
			sdram_rd_bit							<=		4'b0;
		else if(sync_h2l)
			sdram_rd_bit							<=		bit_select1 + bit_dif;
		else if(rd_bit_flag)
			sdram_rd_bit							<=		bit_select2 + bit_dif;
		else
			sdram_rd_bit							<=		bit_select1 + bit_dif;
	end
	//当前读bit通过此标志读取两组数据
	always @(posedge clk) begin
		if(sync)
			rd_bit_flag								<=		1'b0;
		else if(read_sig_h2l)
			rd_bit_flag								<=		~rd_bit_flag;
		else
			rd_bit_flag								<=		rd_bit_flag;
	end
	//读信号,判断当前是否在读状态当中
	always @(posedge clk) begin
		case(next_state)
			SYNC				:	read_sig			<=		1'b0;
			READ_INIT		:	read_sig			<=		1'b1;
			READ_DONE		:	begin
				if(counter == INIT_COUNT - 10'd2 && rd_flag)
					read_sig							<=		1'b0;
				else
					read_sig							<=		read_sig;
			end
			default	:	read_sig					<=		read_sig;
		endcase
	end
	//读地址寄存器
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	sdram_rdaddress	<=		15'b0;
			READ_INIT	:	sdram_rdaddress	<=		port0_addr;
			READ			:	begin
				if(!sdram_ctrl_waitrequest) begin
					case(cnt_c)
						4'd0	:	sdram_rdaddress	<=		port0_addr;
						4'd1	:	sdram_rdaddress	<=		port1_addr;
						4'd2	:	sdram_rdaddress	<=		port2_addr;
						4'd3	:	sdram_rdaddress	<=		port3_addr;
						4'd4	:	sdram_rdaddress	<=		port4_addr;
						4'd5	:	sdram_rdaddress	<=		port5_addr;
						4'd6	:	sdram_rdaddress	<=		port6_addr;
						4'd7	:	sdram_rdaddress	<=		port7_addr;
						4'd8	:	sdram_rdaddress	<=		port8_addr;
						4'd9	:	sdram_rdaddress	<=		port9_addr;
						4'd10	:	sdram_rdaddress	<=		port10_addr;
						4'd11	:	sdram_rdaddress	<=		port11_addr;
					default	:	sdram_rdaddress	<=		sdram_rdaddress;
					endcase
				end
				else
					sdram_rdaddress					<=		sdram_rdaddress;
			end
		default	:	sdram_rdaddress			<=		15'b0;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	rd_flag				<=		1'b0;
			READ_DONE	:	begin
				if(counter == INIT_COUNT && frame_init)
					rd_flag							<=		~rd_flag;
				else
					rd_flag							<=		rd_flag;
			end
			default		:	rd_flag				<=		rd_flag;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	cnt_g					<=		7'b0;
			READ_DONE	:	begin
				if(cnt_h == mod_h && cnt_p == mod_p - 1'b1) begin
					if(cnt_g == mod_g - 1'b1)
						cnt_g							<=		7'b0;
					else
						cnt_g							<=		cnt_g + 1'b1;
				end
			end
			default		:	cnt_g					<=		cnt_g;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	cnt_p					<=		7'b0;
			READ_DONE	:	begin
				if(cnt_h == mod_h) begin
					if(cnt_p == mod_p - 1'b1)
						cnt_p							<=		7'b0;
					else
						cnt_p							<=		cnt_p + 1'b1;
				end
			end
			default		:	cnt_p					<=		cnt_p;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	cnt_h					<=		6'b0;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_l == mod_l - 1'b1 && cnt_c == mod_c - 1'b1 && rd_flag && rd_bit_flag)
					cnt_h								<=		cnt_h + 1'b1;
				else
					cnt_h								<=		cnt_h;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					cnt_h								<=		6'b0;
				else
					cnt_h								<=		cnt_h;
			end
			default		:	cnt_h					<=		cnt_h;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	cnt_l					<=		5'b0;
			READ_INIT	:	begin
				if(counter == 10'd0)
					cnt_l								<=		5'b0;
				else
					cnt_l								<=		cnt_l + 1'b1;
			end
			READ			:	begin
				if(!sdram_ctrl_waitrequest) begin
					if(cnt_l == mod_l - 1'b1)
						cnt_l							<=		5'b0;
					else
						cnt_l							<=		cnt_l + 1'b1;
				end
			end
		default			:	cnt_l					<=		5'b0;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	cnt_c					<=		4'b0;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_l == mod_l - 1'b1)
					cnt_c								<=		cnt_c + 1'b1;
				else
					cnt_c								<=		cnt_c;
			end
			default		:	cnt_c					<=		4'b0;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port0_addr			<=		port0_init;
			READ_INIT	:	begin
				if(counter == 10'd0)
					port0_addr						<=		port0_addr;
				else
					port0_addr						<=		port0_addr + 1'b1;
			end
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd0) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port0_addr					<=		port0_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port0_addr					<=		port0_addr - mod_l + 1'b1;
					else
						port0_addr					<=		port0_addr + 1'b1;
				end
				else
					port0_addr						<=		port0_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port0_addr						<=		port0_init;
				else
					port0_addr						<=		port0_addr;
			end
		default	:	port0_addr					<=		port0_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port1_addr			<=		port1_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd1) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port1_addr					<=		port1_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port1_addr					<=		port1_addr - mod_l + 1'b1;
					else
						port1_addr					<=		port1_addr + 1'b1;
				end
				else
					port1_addr						<=		port1_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port1_addr						<=		port1_init;
				else
					port1_addr						<=		port1_addr;
			end
		default	:	port1_addr					<=		port1_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port2_addr			<=		port2_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd2) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port2_addr					<=		port2_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port2_addr					<=		port2_addr - mod_l + 1'b1;
					else
						port2_addr					<=		port2_addr + 1'b1;
				end
				else
					port2_addr						<=		port2_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port2_addr						<=		port2_init;
				else
					port2_addr						<=		port2_addr;
			end
		default	:	port2_addr					<=		port2_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port3_addr			<=		port3_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd3) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port3_addr					<=		port3_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port3_addr					<=		port3_addr - mod_l + 1'b1;
					else
						port3_addr					<=		port3_addr + 1'b1;
				end
				else
					port3_addr						<=		port3_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port3_addr						<=		port3_init;
				else
					port3_addr						<=		port3_addr;
			end
		default	:	port3_addr					<=		port3_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port4_addr			<=		port4_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd4) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port4_addr					<=		port4_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port4_addr					<=		port4_addr - mod_l + 1'b1;
					else
						port4_addr					<=		port4_addr + 1'b1;
				end
				else
					port4_addr						<=		port4_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port4_addr						<=		port4_init;
				else
					port4_addr						<=		port4_addr;
			end
		default	:	port4_addr					<=		port4_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port5_addr			<=		port5_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd5) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port5_addr					<=		port5_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port5_addr					<=		port5_addr - mod_l + 1'b1;
					else
						port5_addr					<=		port5_addr + 1'b1;
				end
				else
					port5_addr						<=		port5_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port5_addr						<=		port5_init;
				else
					port5_addr						<=		port5_addr;
			end
		default	:	port5_addr					<=		port5_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port6_addr			<=		port6_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd6) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port6_addr					<=		port6_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port6_addr					<=		port6_addr - mod_l + 1'b1;
					else
						port6_addr					<=		port6_addr + 1'b1;
				end
				else
					port6_addr						<=		port6_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port6_addr						<=		port6_init;
				else
					port6_addr						<=		port6_addr;
			end
		default	:	port6_addr					<=		port6_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port7_addr			<=		port7_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd7) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port7_addr					<=		port7_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port7_addr					<=		port7_addr - mod_l + 1'b1;
					else
						port7_addr					<=		port7_addr + 1'b1;
				end
				else
					port7_addr						<=		port7_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port7_addr						<=		port7_init;
				else
					port7_addr						<=		port7_addr;
			end
		default	:	port7_addr					<=		port7_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port8_addr			<=		port8_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd8) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port8_addr					<=		port8_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port8_addr					<=		port8_addr - mod_l + 1'b1;
					else
						port8_addr					<=		port8_addr + 1'b1;
				end
				else
					port8_addr						<=		port8_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port8_addr						<=		port8_init;
				else
					port8_addr						<=		port8_addr;
			end
		default	:	port8_addr					<=		port8_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port9_addr			<=		port9_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd9) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port9_addr					<=		port9_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port9_addr					<=		port9_addr - mod_l + 1'b1;
					else
						port9_addr					<=		port9_addr + 1'b1;
				end
				else
					port9_addr						<=		port9_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port9_addr						<=		port9_init;
				else
					port9_addr						<=		port9_addr;
			end
		default	:	port9_addr					<=		port9_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port10_addr			<=		port10_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd10) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port10_addr					<=		port10_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port10_addr					<=		port10_addr - mod_l + 1'b1;
					else
						port10_addr					<=		port10_addr + 1'b1;
				end
				else
					port10_addr						<=		port10_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port10_addr						<=		port10_init;
				else
					port10_addr						<=		port10_addr;
			end
		default	:	port10_addr					<=		port10_addr;
		endcase
	end
	
	always @(posedge clk) begin
		case(next_state)
			SYNC			:	port11_addr			<=		port11_init;
			READ			:	begin
				if(!sdram_ctrl_waitrequest && cnt_c == 4'd11) begin
					if(cnt_l == mod_l - 1'b1 && rd_flag && rd_bit_flag)
						port11_addr					<=		port11_addr + mod_v;
					else if(cnt_l == mod_l - 1'b1)
						port11_addr					<=		port11_addr - mod_l + 1'b1;
					else
						port11_addr					<=		port11_addr + 1'b1;
				end
				else
					port11_addr						<=		port11_addr;
			end
			READ_DONE	:	begin
				if(cnt_h == mod_h && counter == INIT_COUNT)
					port11_addr						<=		port11_init;
				else
					port11_addr						<=		port11_addr;
			end
		default	:	port11_addr					<=		port11_addr;
		endcase
	end
	
	always @(posedge clk or negedge rst_n) begin
		if(!rst_n)
			frame_init								<=		1'b0;
		else begin
			if(sdram_ctrl_address == MOD_DONE - 1'b1)
				frame_init							<=		1'b1;
		end
	end
	
endmodule
  • 写回答

3条回答 默认 最新

  • 九五656 2021-02-02 18:46
    关注

    刚从这上面看到这条路径非常长,是这个的问题吗?

    评论

报告相同问题?

悬赏问题

  • ¥15 无线电能传输系统MATLAB仿真问题
  • ¥50 如何用脚本实现输入法的热键设置
  • ¥20 我想使用一些网络协议或者部分协议也行,主要想实现类似于traceroute的一定步长内的路由拓扑功能
  • ¥30 深度学习,前后端连接
  • ¥15 孟德尔随机化结果不一致
  • ¥15 apm2.8飞控罗盘bad health,加速度计校准失败
  • ¥15 求解O-S方程的特征值问题给出边界层布拉休斯平行流的中性曲线
  • ¥15 谁有desed数据集呀
  • ¥20 手写数字识别运行c仿真时,程序报错错误代码sim211-100
  • ¥15 关于#hadoop#的问题