基于FPGA的updata大综合设计

1.原理图,这次的协议是7*55/d5/aa(擦出flash)55(在flash中写入数据)。因此frame的控制模块至关重要。

2.仿真结果

   这是仿真的frame控制模过滤协议之后产生的擦除地址与标志位,图中可以看出能够产生。

    这是flash的擦除模块,这是flash模块中的扇区自动加一,这次擦除了8个扇区。

     这是擦除完成的标志位,回传55表示擦除完成。

        这是仿真在协议模块中过滤协议之后,产生写的地址、写地址标志位、写数据以及写数据的标志位。

          通过观察flash的写控制模块可以发现flash可以写入相应的数据。

    通过观察uart的tx模块端,结束标志位产生后,可以回传aa(16进制)

3.这次大综合需要用到的模块uart的rx模块和tx模块、flash的擦除模块和写入模块、按键消抖和icapIP核模块以及利用top模块将所有模块综合。

module rx_crtl(

		input wire sclk,
		input wire rst_n,
		input wire rx_in,
		
		output reg stop_flag,   //新增数据监测停止位
		output reg flag_o,
		output reg [7:0] data_o
);

reg [12:0] cnt;
reg [3:0]  bit_cnt;
reg rx_in_1,rx_in_2;
reg rx_en;     //使能信号值有问题
reg bit_flag;
reg [7:0]tmp_data;
reg tmp_flag;

reg [16:0] cnt_clean;

parameter CNT_CLEAN=100000;//28888; 仿真多写1个4
parameter	CNT=5207;
parameter   BIT_CNT=8;
parameter   bit_flag_cnt=2603;  //	产生bit采集标志位
//parameter   clean_flag=2610;


always@(posedge sclk or negedge rst_n)   //ram输入信号清零计数器
		if(!rst_n)
		cnt_clean<=16'd0;
		else if(flag_o==1'b1)			//  少写了清零条件,导致写地址一直处于清零状态
				cnt_clean<=16'd0;		
		else if(cnt_clean==CNT_CLEAN)
					cnt_clean<=cnt_clean;	// 优先级,当时产生清零标志位没有保持,而是清零导致产生无数个终端位
		else if(flag_o==1'b0)  		 	//flag_o==1'b1,当时想的就是拉高开始计数,结果发现根本不计数
			cnt_clean<=cnt_clean+1'b1;	//因为标志位拉高只有一个时钟周期,应该记拉低的时钟周期。
			

always@(posedge sclk or negedge rst_n)  //数据清零位传递给帧协议
		if(!rst_n)
		stop_flag<=1'b0;
		else if (cnt_clean==CNT_CLEAN-1)
				stop_flag<=1'b1;
		else 	stop_flag<=1'b0;

always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			rx_in_1<=1'b1;
		else rx_in_1<=rx_in;
always@(posedge sclk or negedge rst_n)  //输入信号延时
		if(!rst_n)
			rx_in_2<=1'b1;
		else rx_in_2<=rx_in_1;

always@(posedge sclk or negedge rst_n)   //产生计数使能信号
		if(!rst_n)
			rx_en<=1'b0;
		else if(rx_in_1==1'b0&&rx_in_2==1'b1)
			rx_en<=1'b1;
			else if(bit_cnt==BIT_CNT&&cnt==CNT)
			 rx_en<=1'b0;
			 
always@(posedge sclk or negedge rst_n)
		if(!rst_n)	
			cnt<=13'd0;
			else if(rx_en==1'b0)
				  cnt<=13'd0;
				  else if(cnt==CNT)
						cnt<=13'd0;
				  	else if(rx_en==1'b1)
				  			cnt<=cnt+1'b1;
				 
always@(posedge sclk or negedge rst_n)   //位宽计数
		if(!rst_n)	
			bit_cnt<=4'd0;
				else if(rx_en==1'b0)	
					bit_cnt<=4'd0;
				else if(bit_cnt==BIT_CNT&&cnt==CNT)	
					bit_cnt<=4'd0;	
					else if(cnt==CNT)
						bit_cnt<=bit_cnt+1'b1;

always@(posedge sclk or negedge rst_n)   //产生bit标志位
		if(!rst_n)
			bit_flag<=1'b0;
			else if(cnt==bit_flag_cnt)	
				bit_flag<=1'b1;
				else bit_flag<=1'b0;	

always@(posedge sclk or negedge rst_n)   //数据拼接
		if(!rst_n)	
			tmp_data<=8'd0;
		else if(bit_flag==1'b1&&bit_cnt>=4'd1&&bit_cnt<=4'd8)
				tmp_data<={rx_in_2,tmp_data[7:1]}; 		//少写分号
														//else if(bit_cnt==BIT_CNT&&cnt==clean_flag)  数据不清零条件
														//		tmp_data<=8'd0;

always@(posedge sclk or negedge rst_n)   //数据拼接完成标志
		if(!rst_n)	
		 tmp_flag<=1'b0;
		 else if(bit_flag==1'b1&&bit_cnt==BIT_CNT)
		 	tmp_flag<=1'b1;
		 	else tmp_flag<=1'b0;

always@(posedge sclk or negedge rst_n)
		if(!rst_n)	
			data_o<=8'd0;
		else if(tmp_flag==1'b1)
			data_o<=tmp_data;

always@(posedge sclk or negedge rst_n)
		if(!rst_n)			
			flag_o<=1'b0;
			else flag_o<=tmp_flag;	 
endmodule
module	w_farme(
		
		input wire 			sclk,
		input wire 			rst_n,
		input wire 			flag_uart,
		input wire 	[7:0] 	data_uart,
		input wire 			stop_flag,		//数据发送完成标志
		input wire			sen_stop_flag,  //擦除完成标识
		
		output reg 			wr_flag,		
		output reg 	[23:0]	wr_addr,
		output reg	[7:0]	wr_data,
		output	reg			wr_flag_dizhi,
		
		output	reg	[23:0]	se_addr,
		output	reg			se_flag,
		
		output	reg			tx_flag,
		output	reg	[7:0]	tx_data		//擦除结束用55标志,发生完成用aa标识

);

reg [10:0] 	state;
parameter IDLE		=11'b00000_0000_01;
parameter H_1_55	=11'b00000_0000_10;
parameter H_2_55	=11'b00000_0001_00;
parameter H_3_55	=11'b00000_0010_00;
parameter H_4_55	=11'b00000_0100_00;
parameter H_5_55	=11'b00000_1000_00;
parameter H_6_55	=11'b00001_0000_00;
parameter H_7_55	=11'b00010_0000_00;
parameter H_d5		=11'b00100_0000_00;
parameter H_se		=11'b01000_0000_00;
parameter H_wr		=11'b10000_0000_00;

reg		[2:0]		cnt_flag;
reg		[23:0]		tmp_addr;

reg		[2:0]		cnt_flag_wr;
reg		[23:0]		tmp_addr_wr;

reg					flag_uart_dely;
reg					flag_uart_dely1;
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			state<=IDLE;
		//else if(stop_flag==1'b1)
		//		state<=idle;
		 else if(flag_uart==1'b1)
		 			case(state)
		 			IDLE  :  if(data_uart==8'h55)
		 						state<=H_1_55;
		 						else state<=IDLE;
		 			H_1_55:	 if(data_uart==8'h55)
		 						state<=H_2_55;
		 						else state<=IDLE;
		 			H_2_55:	 if(data_uart==8'h55)
		 						state<=H_3_55;
		 						else state<=IDLE;
		 			H_3_55:	 if(data_uart==8'h55)
		 						state<=H_4_55;
		 						else state<=IDLE;
		 			H_4_55:	 if(data_uart==8'h55)
		 						state<=H_5_55;
		 						else state<=IDLE;
		 			H_5_55:	 if(data_uart==8'h55)
		 						state<=H_6_55;
		 						else state<=IDLE;
		 			H_6_55:	 if(data_uart==8'h55)
		 						state<=H_7_55;
		 						else state<=IDLE;
		 			H_7_55:	 if(data_uart==8'hd5)
		 						state<=H_d5;
		 						else state<=IDLE;
		 			H_d5:	 if(data_uart==8'haa)
		 						state<=H_se;
		 					 else if(data_uart==8'h55)
		 						state<=H_wr;
		 					 else state<=IDLE;
		 			H_se:	 if(sen_stop_flag==1)
		 						state<=IDLE;
		 					 else state<=state;
		 			H_wr:	 if(stop_flag==1)
		 						state<=IDLE;	
		 					else state<=state;
					default:;
					endcase 

always@(posedge sclk or negedge rst_n)
		if(!rst_n)
		flag_uart_dely<=0;
		else 	flag_uart_dely<=flag_uart;
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
		flag_uart_dely1<=0;
		else 	flag_uart_dely1<=flag_uart_dely;
						
always@(posedge sclk or negedge rst_n)    //产生读计数器,对输入的标志位计数
	if(!rst_n)
		cnt_flag<=2'd0;
	else if(sen_stop_flag==1)
		cnt_flag<=2'd0;
	else if(cnt_flag==5)
		cnt_flag<=cnt_flag;
	else if(state==H_se&&flag_uart_dely==1)	
		cnt_flag<=cnt_flag+1;

always@(posedge sclk or negedge rst_n)    //读地址拼接——目前不确定要不要清零
	if(!rst_n)
		tmp_addr<=24'd0;
	else if(state==H_se&&flag_uart==1&&cnt_flag<=3)
		tmp_addr<={tmp_addr[15:0],data_uart};
	
always@(posedge sclk or negedge rst_n)    //地址发送
	if(!rst_n)
		se_addr<=24'd0;
	else se_addr<=tmp_addr;

always@(posedge sclk or negedge rst_n)    //清除标志位产生
	if(!rst_n)
		se_flag<=0;
	else if(cnt_flag==4)
		se_flag<=flag_uart_dely1;
	else  se_flag<=0;
						
always@(posedge sclk or negedge rst_n)    //产生写计数器,对输入的标志位计数
	if(!rst_n)
		cnt_flag_wr<=2'd0;
	else if(stop_flag==1)
		cnt_flag_wr<=2'd0;
	else if(cnt_flag_wr==5)
		cnt_flag_wr<=cnt_flag_wr;
	else if(state==H_wr&&flag_uart_dely==1)	
		cnt_flag_wr<=cnt_flag_wr+1;

always@(posedge sclk or negedge rst_n)    //写地址拼接——目前不确定要不要清零wr_flag_dizhi
	if(!rst_n)
		tmp_addr_wr<=24'd0;
	else if(state==H_wr&&flag_uart==1&&cnt_flag_wr<=3)
		tmp_addr_wr<={tmp_addr_wr[15:0],data_uart};

always@(posedge sclk or negedge rst_n)    //写地址拼接——目前不确定要不要清零wr_flag_dizhi
	if(!rst_n)
		wr_flag_dizhi<=0;
	else if(cnt_flag_wr==4)
		wr_flag_dizhi<=flag_uart_dely;
	else	wr_flag_dizhi<=0;
	
always@(posedge sclk or negedge rst_n)    //地址发送
	if(!rst_n)
		wr_addr<=24'd0;
	else wr_addr<=tmp_addr_wr;

always@(posedge sclk or negedge rst_n)    //数据发送标志位产生
	if(!rst_n)
		wr_flag<=0;
	else if(cnt_flag_wr>=5)
		wr_flag<=flag_uart_dely1;
	else  wr_flag<=0;

always@(posedge sclk or negedge rst_n)    //写的数据打拍
	if(!rst_n)
		wr_data<=8'd0;
	else if(cnt_flag_wr==5)
		wr_data<=data_uart;
	else if(stop_flag==1)
		wr_data<=8'd0;
	
always@(posedge sclk or negedge rst_n)    //回传数据标志位
	if(!rst_n)
		tx_flag<=0;
	else if(sen_stop_flag==1)
		tx_flag<=1;
	else if(stop_flag==1&&state==H_wr)
		tx_flag<=1;
	else tx_flag<=0;
	
always@(posedge sclk or negedge rst_n)    //回传数据
	if(!rst_n)
		tx_data<=8'd0;
	else if(sen_stop_flag==1)
		tx_data<=8'h55;
	else if(stop_flag==1)
		tx_data<=8'haa;
	else tx_data<=8'd0;	

endmodule
/***************************
spi协议控制flash扇区擦除
****************************/
module flash_ctrl_se(
		
		input	wire		sclk,
		input	wire		rst_n,
		input	wire		pi_se_flag,
		input	wire [23:0] se_addr_in,
		
		output	reg			led,
		output	reg			cs_n,
		output	reg			sck,
		output	reg			sdi,
		output	reg			sent_flag_out			//地址清零结束位

);

reg	[9:0]	state;
parameter	idle		=10'b0000_0000_01;
parameter	WAIT1		=10'b0000_0000_10;
parameter	WRITE		=10'b0000_0001_00;
parameter	WAIT2		=10'b0000_0010_00;
parameter	WAIT3		=10'b0000_0100_00;
parameter	WAIT4		=10'b0000_1000_00;
parameter	SE			=10'b0001_0000_00;
parameter	INIT_ADDR	=10'b0010_0000_00;
parameter	WAIT5		=10'b0100_0000_00;
parameter	WAIT_3S		=10'b1000_0000_00; 	
reg	[4:0]	sclk_cnt;
parameter	SCLK_CNT=31;
reg	[1:0]	cnt_init_addr;
reg	[25:0]	cnt_1s;
parameter	ONE_S=49_9999_99;
reg	[1:0]	cnt_3s;
reg	[1:0]	cnt4;
reg	[2:0]	bit_cnt;
reg	[3:0]	cnt_wait_3s;
reg	[23:0]	init_addr;
parameter	wr_en=8'h06;		//信号差了一个时钟周期
parameter	se_en=8'hd8;
parameter	CNT_wait_3s=7;
reg			cnt_3s_en;

always@(posedge	sclk or negedge rst_n)	//循环擦除
		if(!rst_n)	
			cnt_wait_3s<=3'd0;
		else if(cnt_wait_3s==CNT_wait_3s&&cnt_1s==ONE_S&&cnt_3s==2)
			cnt_wait_3s<=3'd0;
		else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2)
			cnt_wait_3s<=cnt_wait_3s+1'b1;

always@(posedge	sclk or negedge rst_n)	//扇区地址变换
		if(!rst_n)	
		init_addr<=24'd0;
		else if(pi_se_flag==1)
			init_addr<=se_addr_in;
		else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2)  /////
			init_addr<=init_addr+24'h01_0000;
		else if(state==idle)
			init_addr<=24'd0;
					
always@(posedge	sclk or negedge	rst_n)		//为输出时钟计数
		if(!rst_n)
			cnt4<=2'd0;
		else if(cnt4==3)
			cnt4<=2'd0;
		else if(state==WRITE||state==SE||state==INIT_ADDR)
			 cnt4<=cnt4+1;
always@(posedge	sclk or negedge	rst_n)   //	bit位计数
		if(!rst_n)
		bit_cnt<=3'd0;
		else if(bit_cnt==7&&cnt4==3)
		bit_cnt<=3'd0;
		else if(cnt4==3)
				bit_cnt<=bit_cnt+1;
				
always@(posedge	sclk or negedge	rst_n)
		if(!rst_n)
		cnt_1s<=26'd0;
		else if(cnt_1s==ONE_S)
			cnt_1s<=26'd0;
		else if(cnt_3s_en==1)
			cnt_1s<=cnt_1s+1;
always@(posedge	sclk or negedge	rst_n)
		if(!rst_n)
		cnt_3s<=2'd0;
		else if(cnt_1s==ONE_S&&cnt_3s==2)
			cnt_3s<=2'd0;
		else if(cnt_1s==ONE_S)
			cnt_3s<=cnt_3s+1;
always@(posedge	sclk or negedge rst_n)	//3秒使能信号
		if(!rst_n)	
		cnt_3s_en<=0;
		else if(cnt_1s==ONE_S&&cnt_3s==2)
			cnt_3s_en<=0;
		else if(state==WAIT_3S)
			cnt_3s_en<=1;
always@(posedge	sclk or negedge rst_n)
		if(!rst_n)
			cs_n<=1;
		else if(pi_se_flag==1)
			cs_n<=0;
		else if(state==idle)
			cs_n<=1;
		else if(state==WAIT2&&sclk_cnt==SCLK_CNT)		//片选信号没有描述对
			cs_n<=1;
		else if(state==WAIT3&&sclk_cnt==SCLK_CNT)
			cs_n<=0;
		else if(state==WAIT5&&sclk_cnt==SCLK_CNT)
			cs_n<=1;
		else if(state==WAIT_3S&&cnt_1s==ONE_S&&cnt_3s==2)
			cs_n<=0;
		//else if(cnt_wait_3s==CNT_wait_3s)
			//cs_n<=1;		

always@(posedge	sclk or negedge rst_n)
		if(!rst_n)	
			sclk_cnt<=5'd0;
		else if	(sclk_cnt==SCLK_CNT&&cnt_wait_3s==CNT_wait_3s)
			sclk_cnt<=5'd0;
		else if(sclk_cnt==SCLK_CNT)
				sclk_cnt<=5'd0;
		else if(cs_n==0)
			sclk_cnt<=sclk_cnt+1;
		else if(state==WAIT3)
			sclk_cnt<=sclk_cnt+1;				
always@(posedge	sclk or negedge rst_n)   //3位状态计数
		if(!rst_n)
		cnt_init_addr<=2'd0;
		else if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
			cnt_init_addr<=2'd0;
		else if(sclk_cnt==SCLK_CNT&&state==INIT_ADDR)
			cnt_init_addr<=cnt_init_addr+1;
			
always@(posedge	sclk or negedge rst_n)
		if(!rst_n)
			state<=idle;
		else case(state)
				idle:		if(pi_se_flag==1)
								state<=WAIT1;
							else state<=idle;								
				WAIT1:		if(sclk_cnt==SCLK_CNT)
								state<=WRITE;
							else	state<=WAIT1;
				WRITE:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT2;
							else state<=WRITE;
				WAIT2:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT3;
							else 	state<=WAIT2;
				WAIT3:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT4;
							else	state<=WAIT3;
				WAIT4:		if(sclk_cnt==SCLK_CNT)
								state<=SE;
				SE:			if(sclk_cnt==SCLK_CNT)
								state<=INIT_ADDR;
							else state<=SE;
				INIT_ADDR:	if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
								state<=WAIT5;
								else state<=INIT_ADDR;
				WAIT5:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT_3S;
							else	state<=WAIT5;
				WAIT_3S:	if(cnt_1s==ONE_S&&cnt_3s==2)
									state<=WAIT1;
							else if(cnt_wait_3s==CNT_wait_3s) 
									state<=idle;
				default:	state<=idle;
				endcase

								
always@(posedge	sclk or negedge rst_n)	//时钟传递
		if(!rst_n)		
		  sck<=0;
		 else if(state==WRITE &&cnt4==1)	
		 		sck<=1;
		 else if(state==WRITE&&cnt4==3)
		 		sck<=0;
		 else if (state==SE&&cnt4==1)	
		 		sck<=1;
		 else if(state==SE&&cnt4==3)
		 		sck<=0;
		 else if (state==INIT_ADDR&&cnt4==1)	
		 		sck<=1;
		 else if(state==INIT_ADDR&&cnt4==3)
		 		sck<=0;
		 		
always@(posedge	sclk or negedge rst_n)	//低电平传输数据 上升沿采集数据
		if(!rst_n)
			sdi<=1'b1;
		else if(state==WRITE)	
			sdi<=wr_en[7-bit_cnt];
		else if(state==SE)	
			sdi<=se_en[7-bit_cnt];
		else if(state==INIT_ADDR&&cnt_init_addr==0)
			sdi<=init_addr[23-bit_cnt];
		else if(state==INIT_ADDR&&cnt_init_addr==1)
			sdi<=init_addr[15-bit_cnt];
		else if(state==INIT_ADDR&&cnt_init_addr==2)
			sdi<=init_addr[7-bit_cnt];
		else sdi<=1'b1;							//检查发现有问题

always@(posedge	sclk or negedge	rst_n)
			if(!rst_n)
				led<=0;
		else if(cnt_3s_en==1)
				led<=1;
		else	led<=0;
		
always@(posedge	sclk or negedge	rst_n)
			if(!rst_n)
			sent_flag_out<=0;
			else if(cnt_wait_3s==CNT_wait_3s&&cnt_1s==ONE_S&&cnt_3s==2)
				sent_flag_out<=1;
			else sent_flag_out<=0;
			
endmodule
/***************************
spi协议控制flash扇区数据输入
****************************/
module flash_ctrl_wr(
		
		input	wire			sclk,
		input	wire			rst_n,
		input	wire			pi_flag,
		input	wire			pi_flag_dizhi,
		input	wire	[7:0]	data_in,
		input	wire			stop_flag_rx,		//发送端输入的停止位
		input	wire	[23:0]	frame_wr_addr,
		
		output	reg		cs_n,
		output	reg		sck,
		output	reg		sdi
);

reg	[9:0]	state;
parameter	idle		=10'b0000_0000_01;
parameter	WAIT1		=10'b0000_0000_10;
parameter	WRITE		=10'b0000_0001_00;
parameter	WAIT2		=10'b0000_0010_00;
parameter	WAIT3		=10'b0000_0100_00;
parameter	WAIT4		=10'b0000_1000_00;
parameter	PP			=10'b0001_0000_00;
parameter	INIT_ADDR	=10'b0010_0000_00;
parameter	DATA_IN		=10'b0100_0000_00;
parameter	WAIT5		=10'b1000_0000_00; 	
reg	[4:0]	sclk_cnt;
parameter	SCLK_CNT=31;
reg	[1:0]	cnt_init_addr;
reg	[1:0]	cnt4;
reg	[2:0]	bit_cnt;
reg			add_addr_flag;
reg	[23:0]	init_addr;
parameter	INIT_ADDR_Location=6'h00_00_00;
parameter	wr_en=8'h06;
parameter	PP_en=8'h02;


always@(posedge sclk or negedge rst_n)
	if(!rst_n)
		add_addr_flag<=0;
	else if(state==WAIT5&&sclk_cnt==SCLK_CNT)
		add_addr_flag<=1;
	else add_addr_flag<=0;



always@(posedge	sclk or negedge rst_n)	
		if(!rst_n)	
			init_addr<=INIT_ADDR_Location;
		else if(pi_flag_dizhi==1)
				init_addr<=frame_wr_addr;
		else if(add_addr_flag==1)
			init_addr<=init_addr+24'h0000_01; 	//字节自动加一,加到255后页自动加一
		//else init_addr<=24'd0;
					
always@(posedge	sclk or negedge	rst_n)
		if(!rst_n)
			cnt4<=2'd0;
		else if(cnt4==3)
			cnt4<=2'd0;
		else if(state==WRITE||state==PP||state==INIT_ADDR||state==DATA_IN)
			 cnt4<=cnt4+1;
always@(posedge	sclk or negedge	rst_n)
		if(!rst_n)
			bit_cnt<=3'd0;
		else if(bit_cnt==7&&cnt4==3)
			bit_cnt<=3'd0;
		else if(cnt4==3)
				bit_cnt<=bit_cnt+1;
				

always@(posedge	sclk or negedge rst_n)
		if(!rst_n)
			cs_n<=1;
		else if(pi_flag==1)
			cs_n<=0;
		else if(state==WAIT2&&sclk_cnt==SCLK_CNT)
			cs_n<=1;
		else if(state==WAIT3&&sclk_cnt==SCLK_CNT)
			cs_n<=0;
		else if(sclk_cnt==SCLK_CNT&&state==WAIT5)
			cs_n<=1;		
always@(posedge	sclk or negedge rst_n)
		if(!rst_n)	
			sclk_cnt<=5'd0;
		else if	(sclk_cnt==SCLK_CNT&&state==WAIT5)
			sclk_cnt<=5'd0;
		else if(sclk_cnt==SCLK_CNT)	
			sclk_cnt<=5'd0;
		else if(cs_n==0)
			sclk_cnt<=sclk_cnt+1;
		else if(state==WAIT3)
			sclk_cnt<=sclk_cnt+1;

always@(posedge	sclk or negedge rst_n)
		if(!rst_n)
		cnt_init_addr<=2'd0;
		else if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
			cnt_init_addr<=2'd0;
		else if(sclk_cnt==SCLK_CNT&&state==INIT_ADDR)
			cnt_init_addr<=cnt_init_addr+1;
			
always@(posedge	sclk or negedge rst_n)
		if(!rst_n)
			state<=idle;
		else case(state)
				idle:		if(pi_flag==1)
								state<=WAIT1;
							else	state<=idle;
				WAIT1:		if(sclk_cnt==SCLK_CNT)
								state<=WRITE;
							else	state<=WAIT1;
				WRITE:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT2;
							else state<=WRITE;
				WAIT2:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT3;
							else 	state<=WAIT2;
				WAIT3:		if(sclk_cnt==SCLK_CNT)
								state<=WAIT4;
							else	state<=WAIT3;
				WAIT4:		if(sclk_cnt==SCLK_CNT)
								state<=PP;
				PP:			if(sclk_cnt==SCLK_CNT)
								state<=INIT_ADDR;
							else state<=PP;
				INIT_ADDR:	if(cnt_init_addr==2'd2&&sclk_cnt==SCLK_CNT)
								state<=DATA_IN;
								else state<=INIT_ADDR;
				DATA_IN:	if(sclk_cnt==SCLK_CNT)
								state<=WAIT5;
							else	state<=DATA_IN;
				WAIT5:		if(stop_flag_rx)
									state<=idle;
							else if(sclk_cnt==SCLK_CNT)
									state<=idle;
							else state<=WAIT5;
				default:	state<=idle;
				endcase
								
always@(posedge	sclk or negedge rst_n)	//时钟传递
		if(!rst_n)		
		  sck<=0;
		 else if(state==WRITE &&cnt4==1)	
		 		sck<=1;
		 else if(state==WRITE&&cnt4==3)
		 		sck<=0;
		 else if (state==PP&&cnt4==1)	
		 		sck<=1;
		 else if(state==PP&&cnt4==3)
		 		sck<=0;
		 else if (state==INIT_ADDR&&cnt4==1)	
		 		sck<=1;
		 else if(state==INIT_ADDR&&cnt4==3)
		 		sck<=0;
		 else if (state==DATA_IN&&cnt4==1)	
		 		sck<=1;
		 else if(state==DATA_IN&&cnt4==3)
		 		sck<=0;
		 		
always@(posedge	sclk or negedge rst_n)	
		if(!rst_n)
			sdi<=1'b1;
		else if(state==WRITE)	
			sdi<=wr_en[7-bit_cnt];
		else if(state==PP)	
			sdi<=PP_en[7-bit_cnt];
		else if(state==INIT_ADDR&&cnt_init_addr==0)
			sdi<=init_addr[23-bit_cnt];
		else if(state==INIT_ADDR&&cnt_init_addr==1)
			sdi<=init_addr[15-bit_cnt];
		else if(state==INIT_ADDR&&cnt_init_addr==2)
			sdi<=init_addr[7-bit_cnt];
		else if(state==DATA_IN)
			 sdi<=data_in[7-bit_cnt];
		else sdi<=1'b1;							

endmodule
module key_rock(
		input wire sclk,
		input wire rst_n,
		input wire key_in,
		
		output reg key_o
);
reg [18:0] cnt;
parameter CNT_MAX=500000-1;
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			cnt<=1'b0;
			 else if(key_in==1)
					cnt<=0;
					else if(cnt==CNT_MAX)
						 cnt<=cnt;
					else
							cnt<=cnt+1'b1;
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			key_o<=1'b0;
			else if (cnt==CNT_MAX-1)
			 key_o<=1'b1;
			 else
			 key_o<=1'b0;
endmodule
module	icap_ctrl(
		
		input	wire			sclk,
		input	wire			rst_n,
		input	wire			key_in,
		input	wire	[23:0]	wr_addr_frame
);

reg		[3:0]		cnt;
reg					ce;
reg		[15:0]		tmp_i;
wire	[15:0]		i_data;

always@(posedge sclk or negedge rst_n)		//cnt14
		if(!rst_n)
			cnt<=4'd0;
		else if(cnt==14)
			cnt<=4'd0;
		else if (ce==0)
			cnt<=cnt+1'b1;
	
always@(posedge sclk or negedge rst_n)  //ce
		if(!rst_n)
			ce<=1'b1;
		else if(cnt==14)
			ce<=1'b1;
		else if (key_in==1)		//不是很理解
			ce<=1'b0;

always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			tmp_i<=16'hffff;
		else 	case(cnt)
					0:	tmp_i<=16'hffff;
					1:	tmp_i<=16'haa99;
					2:	tmp_i<=16'h5566;
					3:	tmp_i<=16'h3261;
					4:	tmp_i<=wr_addr_frame[15:0];	//{data_uart,tmp_addr[7:0]};
					5:	tmp_i<=16'h3281;
					6:	tmp_i<={8'h03,wr_addr_frame[23:16]};//
					7:	tmp_i<=16'h32a1;
					8:	tmp_i<=16'h0000;	//
					9:	tmp_i<=16'h32c1;
				   10:	tmp_i<=16'h0300;	//
				   11:	tmp_i<=16'h30a1;
				   12:	tmp_i<=16'h000e;
				   13:	tmp_i<=16'h2000;
				   14:	tmp_i<=16'hffff;
			  default:	tmp_i<=16'hffff;
			endcase
assign i_data={tmp_i[8],tmp_i[9],tmp_i[10],tmp_i[11],tmp_i[12],tmp_i[13],tmp_i[14],tmp_i[15],
		   tmp_i[0],tmp_i[1],tmp_i[2],tmp_i[3],tmp_i[4],tmp_i[5],tmp_i[6],tmp_i[7]};



ICAP_SPARTAN6 #(
   .DEVICE_ID(28'h4000093),     // Specifies the pre-programmed Device ID value
   .SIM_CFG_FILE_NAME("NONE")  // Specifies the Raw Bitstream (RBT) file to be parsed by the simulation
                               // model
)
ICAP_SPARTAN6_inst (
   .BUSY(),   // 1-bit output: Busy/Ready output
   .O(),         // 16-bit output: Configuartion data output bus
   .CE(ce),       // 1-bit input: Active-Low ICAP Enable input
   .CLK(sclk),     // 1-bit input: Clock input
   .I(i_data),         // 16-bit input: Configuration data input bus
   .WRITE(1'b0)  // 1-bit input: Read/Write control input
);

endmodule
module tx_crtl(

			input wire sclk,
			input wire rst_n,
			input wire [7:0] data_in,
			input wire flag_in,
			
			output reg data_o

);

reg	[12:0]	cnt;
reg	[3:0]   bit_cnt;
reg			tx_en;
parameter  CNT=5207;
parameter  BIT_CNT=8;
reg	[7:0]	data_in_dely;

always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			data_in_dely<=8'd0;
		else if(flag_in==1)
			data_in_dely<=data_in;
		else if(tx_en==0)
			data_in_dely<=8'd0;
//tx_en
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
			tx_en<=1'b0;
			else if(flag_in==1'b1)
				tx_en<=1'b1;
			else if(bit_cnt==BIT_CNT&&cnt==CNT)
			tx_en<=1'b0;
//cnt 波特率计数
always@(posedge sclk or negedge rst_n)	
		if(!rst_n)		
			cnt<=13'd0;
		else if(cnt==CNT)	
			cnt<=13'd0;
			else if(tx_en==1'b1)	  //条件没写对
					cnt<=cnt+1'b1;
				
//bit_cnt 字节统计
always@(posedge sclk or negedge rst_n)	
		if(!rst_n)	
			bit_cnt<=4'd0;
		else if(tx_en==1'b0)
				bit_cnt<=4'd0;
		else if(bit_cnt==BIT_CNT&cnt==CNT)
				bit_cnt<=4'd0;
			else if(cnt==CNT)
				bit_cnt<=bit_cnt+1'b1;
				
//输出数据控制
always@(posedge sclk or negedge rst_n)	
		if(!rst_n)	
		data_o<=1'b1;
		else if(tx_en==1'b0)  //flag_in==1'b1
			data_o<=1'b1;
		else if(bit_cnt==10'd0)  //flag_in==1'b1
			data_o<=1'b0;
			else if(bit_cnt==10'd1)
				data_o<=data_in_dely[0];
			else if (bit_cnt==10'd2)
				data_o<=data_in_dely[1];
			else if(bit_cnt==10'd3)
				data_o<=data_in_dely[2];
			else if(bit_cnt==10'd4)
				data_o<=data_in_dely[3];
			else if(bit_cnt==10'd5)	
		  		data_o<=data_in_dely[4];
		  	else if(bit_cnt==10'd6)
		  		data_o<=data_in_dely[5];
			else if(bit_cnt==10'd7)
				data_o<=data_in_dely[6];
			else if(bit_cnt==10'd8)
				data_o<=data_in_dely[7];
			//else if(bit_cnt==BIT_CNT)
			//		data_o<=1'b1;
				else data_o<=1'b1;
					
endmodule
module	top_updata(
		
		input	wire 		sclk,
		input	wire		rst_n,
		input	wire		rx_uart_data,
		input	wire		key_in,
		
		output	wire		tx_data,
		output	wire		led,
		output	wire		cs_n,
		output	wire		sck,
		output	wire		sdi
);

wire			key_inst_o;
wire			stop_flag_rx; 
wire			flag_o_rx;
wire	[7:0]	data_o_rx;
wire			wr_flag_frame_inst;
wire	[23:0]	wr_addr_frame_inst;  
wire	[7:0]	wr_data_inst;
wire			se_flag_frame;
wire	[23:0]	se_addr_frame;
wire			sent_flag_out_se_inst;
wire			tx_flag_frame;
wire	[7:0]	tx_data_farme;
wire			wr_inst_cs_n;
wire			wr_inst_sck;
wire			wr_inst_sdi;
wire			se_inst_cs_n;
wire			se_inst_sck;
wire			se_inst_sdi;
wire			wr_flag_dizhi;

assign		cs_n=(wr_inst_cs_n&&se_inst_cs_n);
assign		sck=(wr_inst_sck||se_inst_sck);
assign		sdi=(wr_inst_sdi&&se_inst_sdi);

key_rock	key_rock_inst(
			.sclk		(sclk),
			.rst_n		(rst_n),
			.key_in		(key_in),
			.key_o      (key_inst_o)
);

icap_ctrl	icap_ctrl_inst(
		
			.sclk			(sclk),
			.rst_n			(rst_n),
			.key_in			(key_inst_o),
			.wr_addr_frame  (wr_addr_frame_inst)
);

rx_crtl		rx_crtl_inst(

		.sclk		(sclk),
		.rst_n		(rst_n),
		.rx_in		(rx_uart_data),
		.stop_flag	(stop_flag_rx), 
		.flag_o		(flag_o_rx),
		.data_o     (data_o_rx)
);

w_farme	w_farme_inst(
		
			.sclk			(sclk),
			.rst_n			(rst_n),
			.flag_uart		(flag_o_rx),
			.data_uart		(data_o_rx),
			.stop_flag		(stop_flag_rx),		//数据发送完成标志
			.sen_stop_flag	(sent_flag_out_se_inst),  //擦除完成标识
			.wr_flag_dizhi	(wr_flag_dizhi),
			.wr_flag		(wr_flag_frame_inst),		
			.wr_addr		(wr_addr_frame_inst),
			.wr_data		(wr_data_inst),
		
			.se_addr			(se_addr_frame),
			.se_flag			(se_flag_frame),
		
			.tx_flag	(tx_flag_frame),
			.tx_data	(tx_data_farme)	//擦除结束用55标志,发生完成用aa标识
);

flash_ctrl_wr	flash_ctrl_wr_inst(
		
				.sclk			(sclk),
				.rst_n			(rst_n),
				.pi_flag		(wr_flag_frame_inst),
				.data_in		(wr_data_inst),
				.stop_flag_rx	(stop_flag_rx),		//发送端输入的停止位
				.frame_wr_addr	(wr_addr_frame_inst),
				.pi_flag_dizhi	(wr_flag_dizhi),
				.cs_n			(wr_inst_cs_n),
				.sck			(wr_inst_sck),
				.sdi            (wr_inst_sdi)
);

flash_ctrl_se	flash_ctrl_se_inst(
		
			.sclk			(sclk),
			.rst_n			(rst_n),
			.pi_se_flag		(se_flag_frame),
			.se_addr_in		(se_addr_frame),
		
					.led			(led),
					.cs_n			(se_inst_cs_n),
					.sck			(se_inst_sck),
					.sdi			(se_inst_sdi),
					.sent_flag_out	(sent_flag_out_se_inst)		//地址清零结束位

);

tx_crtl	tx_crtl_inst(

			.sclk		(sclk),
			.rst_n		(rst_n),
			.data_in	(tx_data_farme),
			.flag_in	(tx_flag_frame),
			
			.data_o    (tx_data)

);

endmodule
`timescale	1ns/1ns    
module	tb_update;
        reg		sclk;
        reg		rst_n;
        reg		rx;
        

        
        reg[7:0] a_mem[18:0];	//当前为测试flash写模块 擦出数据为55 55 55 55 55 55 55 d5 aa 10 00 00
        
        initial   $readmemh("./data.txt", a_mem);	//测试flash写入数据为55 55 55 55 55 55 55 d5 55 10 00 00 01 02 03 04 05 aa 55 
        initial
        	begin
        		sclk	=	1'b1;
        		rst_n	<=	1'b0;
        		#300
        		rst_n	<=	1'b1;
        	end
        
        always	#10	sclk	=	~sclk;
        
        initial
        	begin
        		rx	<=	1'b1;
        		#2000
        		rx_byte();
        	end
        
        task	rx_byte();
    
        	integer	j;//定义一个整型变量
        	for(j=0;j<19;j=j+1)//for循环   测试的时候,数据加到原来的256应该是86
        		rx_bit(a_mem[j]);//a_mem[j]是data.txt文件里面第j个8比特数据
        				//j每次取一个值,就调用一次rx_bit();
        				//一共调用256次
	endtask
        
        task	rx_bit(input  [7:0]	data);//data是a_mem[j]的值。
        	integer	i;
        	for(i=0;i<10;i=i+1)
        		begin
        			case(i)
        			0:	rx	<=	1'b0;//起始位
        			1:	rx	<=	data[0];
        			2:	rx	<=	data[1];
        			3:	rx	<=	data[2];
        			4:	rx	<=	data[3];
        			5:	rx	<=	data[4];
        			6:	rx	<=	data[5];
        			7:	rx	<=	data[6];
        			8:	rx	<=	data[7];
        			//上面8个发送的是数据位
        			9:	rx	<=	1'b1;//停止位
        			endcase
        			#104140;//一个波特时间=sclk周期*波特计数器	
        		end
	endtask
	
defparam 	top_updata_inst.flash_ctrl_se_inst.ONE_S=500;
//defparam 	top_updata_inst.rx_crtl_inst.CNT=9;
//defparam 	top_updata_inst.rx_crtl_inst.bit_flag_cnt=4;
//defparam 	top_updata_inst.tx_crtl_inst.CNT=10;
	
top_updata	top_updata_inst(
		
			.sclk			(sclk),
			.rst_n			(rst_n),
			.rx_uart_data	(rx),
			.key_in          ()
);
		
endmodule

4.这次比较难调试的frame_ctrl模块,多次仿真最终达到目的

5.如果仿真通过,下载只办卡却没有达到应有效果,就需要利用ise的chipscope对内部信号进行抓取。

6.擦除调试如图:

猜你喜欢

转载自blog.csdn.net/Headogerz/article/details/82346431