PROJECT 2

module flash_ahb_slave_if (
	//input signals
		hclk,
		hresetn,
		hsel,
		hready_in,
		hwrite,
		hsize,
		htrans,
		hburst,
		hwdata,
		haddr,
		
			flash_rdata,
			flash_prog_done,
			flash_pe_done,
			flash_busy,
			
			eflash_wp_n,
			addr_offset,//used for boot area
			boot_en,
			hready_flag,

	//output signals
		hready_out,
		hresp,
		hrdata,
	
			flash_prog_en,	//program enable
			flash_pe_en,	//page erase enable
			flash_rd_en,	//read enable
			
			rd_inf0_sel,
			rd_inf1_sel,
			rd_main0_sel,
			rd_main1_sel,
			flash0_rd_cs,
			flash1_rd_cs,
			
			prog_infrarea0_sel,
			prog_infrarea1_sel,
			prog_mainarea0_sel,
			prog_mainarea1_sel,

			pe_num,
			pe_main_infr_sel,
			flash_addr_out,
			flash_wdata,
			flash_ctrl_int, //use for interupt controller
		
		
	//flash operation configuration for timing
			t_nvstr_setup,
			t_nvstr_hold,
			t_rcv,
			
			t_prog_setup,
			t_prog_hold,
			t_addr_setup,
			t_addr_hold,
			t_prog_proc,
			
			t_addr_aces,
			
			t_page_erase

);
input hclk;
input hsel;
//总线上其它slave是否全部IDLE(全IDLE才可以工作),
//其它slave有hready为低,则总线在满,这个hready_in也为低
input hready_in;
input hwrite;
input [2:0] 	hsize;
input [2:0] 	hburst;
input [1:0] 	htrans;
input [31:0] 	hwdata;
input [31:0] 	haddr;

//从flash读出的地址,传输到AHB Bus 
//(如果不在配置寄存器则直接赋值给hrdata输出到总线)
input [31:0] 	flash_rdata;

input flash_prog_done;
input flash_pe_done;
input flash_busy;
input eflash_wp_n;
input boot_en;
input [4:0] addr_offset;
input hready_flag;

//output signals
output hready_out;
output [1:0] hresp;
//------------------------------------------------------//
//AHB read data output.
//hrdata = if(status_sel) flash_status_r
//			else (flash_cs) flash_rdata
//读配置寄存器,或者flash
//------------------------------------------------------//
output [31:0] hrdata;

output flash_prog_en;
output flash_pe_en;
output flash_rd_en;
	
output rd_inf0_sel;
output rd_inf1_sel;
output rd_main0_sel;
output rd_main1_sel;
output flash0_rd_cs;
output flash1_rd_cs;
output prog_infrarea0_sel;
output prog_infrarea1_sel;
output prog_mainarea0_sel;
output prog_mainarea1_sel;
output [8:0] pe_num;
output pe_main_infr_sel;

//给Flash的地址一共15bit
output [14:0] flash_addr_out;
output [31:0] flash_wdata;
output flash_ctrl_int; //use for interrupt controller

//flash operation configuration for timing
output [11:0] 	t_nvstr_setup;
output [11:0] 	t_nvstr_hold;
output [7:0] 	t_rcv;
	
output [15:0] 	t_prog_setup;
output [3:0] 	t_prog_hold;
output [3:0] 	t_addr_setup;
output [3:0] 	t_addr_hold;
output [15:0] 	t_prog_proc;

output [7:0] 	t_addr_aces;

output [23:0] 	t_page_erase;

//----------------------------------------------//
// register used for temp the ahb input signas
reg 		hwrite_r	;
reg [2:0] 	hsize_r		;
reg [1:0] 	htrans_r	;
reg [2:0] 	hburst_r	;
reg [31:0] 	haddr_r		;

//flash operation config register
//common timing
reg [31:0] nvstr_setup_timing;
reg [31:0] nvstr_hold_timing;
reg [31:0] rcv_timing;

//program timing
reg [31:0] prog_setup_timing;
reg [31:0] progaddr_sethold_timing;
reg [31:0] prog_proc_timing;

//read timing
reg [31:0] rd_aces_timing;

//page erase timing
reg [31:0] pe_timing;

//Address register and progam data register used for 
//flash program or page erase operation
reg [31:0] prog_addr_r;
reg [31:0] prog_data_r;
reg [31:0] prog_data1_r;
reg [31:0] prog_data2_r;
reg [31:0] prog_data3_r;
reg [31:0] invalid_data_r;

//falsh program/page erase operation control registers 
//and main/info mem selected mark
//wr_en_r[0]:flash prog enable
//pe_en_r[0]:flash page erase enable
reg wr_en_r;
reg pe_en_r;
reg main_infr_sel;

//AHN Bus transactions
parameter	IDLE 	= 2'b00;
parameter	BUSY	= 2'b01;
parameter	NONSEQ 	= 2'b10;
parameter	SEQ		= 2'b11;


//Soc总线地址分配使用到 0x0028_1FFF  ,所以识别控制寄存器地址
//以及MAIN INFR 地址判断到24位[23:0]  
// REG  :	0x0006_0000~0x0006_0fff	:haddr[23:12] = 12'h060
// INFR :	0x0006_1000~0x0006_7fff :
// INFR :	0x0006_1000~0x0006_13ff    0110_0001_0000_0000
// INFR :	0x0006_1400~0x0006_17ff    0110_0100_0000_0000
parameter	REG_ADDR	= 12'h060;	
parameter	INFR_ADDR	= 12'h061;	
parameter	INFR0_ADDR	= 1'h0;		
parameter	INFR1_ADDR	= 2'h1;		

// MAIN	: 	0000_0000 ~ 0003_ffff	:haddr[23:15] = 6'h00
// MIAN0:	0000_0000 ~ 0001_ffff	:haddr[17:16] = 0-
// MIAN1:	0002_0000 ~ 0003_ffff:	haddr[17:16] = 1-
parameter	MAIN_ADDR	= 6'h0;		
parameter	MAIN0_ADDR	= 1'b0;		
parameter   MAIN1_ADDR	= 1'b1;		

//时序控制寄存器的地址偏移,在在控制寄存器初始地址
//加上偏移地址就是相应控制寄存器的地址
//timing configuration register address
parameter	NVSTR_SETUP_ADDR		= 8'h00,
			NVSTR_HOLD_ADDR			= 8'h04,
			PROG_SETUP_ADDR			= 8'h08,
			PROGADDR_SETHOLD_ADDR	= 8'h0c,
			PROG_PROC_ADDR          = 8'h10,
			RD_ACES_ADDR            = 8'h14,
			PE_ADDR                 = 8'h18,
			RCV_ADDR                = 8'h1c,
			WR_EN_ADDR              = 8'h20,
			PE_CONFIG_ADDR          = 8'h24,
			PE_NUM_ADDR             = 8'h28,
			PE_MIANINFR_SEL_ADDR    = 8'h2c,
			PROG_ADDR_ADDR          = 8'h30,
			PROG_DATA_ADDR          = 8'h34,
			INT_EN_ADDR             = 8'h38,
			FLASH_STATUS_ADDR       = 8'h3c,
			BOOT_ERROR_ADDR         = 8'h40,
			PROG_DATA1_ADDR         = 8'h44,			
			PROG_DATA2_ADDR         = 8'h48,
			PROG_DATA3_ADDR         = 8'h50,
			PROG_NUM_ADDR			= 8'h54;
		
//-----------------------------------------------------//
//Generate AHB slave output signals:hready_out & hresp //
//flash prog 	: hready_out = 1;					   //
//flash pe 		: hready_out = 1;					   //
//flash read 	: if(reg_operation) hready_out = 1;	   //
//					else hready_out =flash_rd_ready	   //
//-----------------------------------------------------//
//hready_flag 是控制器那边给的接口模块的,然后AHB总线判断
//ready了,就可以进行读取数据了
//hresp这里直接赋值00,表示response只有OK这种状态,其它不考虑

assign 	hready_out = hready_flag;
assign	hresp = 2'b00;

//---------------------------------------------//
//Generate AHB write and read enable signals   //
//ahb_wr_en 	: htrasn_r and hwrite_r		   //
//ahb_rd_en 	: htrasn_r and hwrite_r		   //
//---------------------------------------------//
//ahb_wr_en 当写信号有效、flash不处在busy状态、
//并且htrans不为IDLE或者BUSY,则有效
//ahb_wr_en  不用判断flash_busy 因为在读的时候有hready信号判断

assign ahb_wr_en = ((htrans == NONSEQ)||(htrans == SEQ)) && hwrite_r && (!flash_busy);
assign ahb_rd_en = ((htrans == NONSEQ)||(htrans == SEQ)) && (!hwrite_r);

//---------------------------------------------//
//flash input data and address.
//flash_addr 		:	haddr_r[17:0] => 64KBytes row address
//flash_addr_out 	:	haddr_r[17:2] => double word (32bits) align
//flash_wdata 		:	when prog,prog_data_r
//
//		NOTE:haddr_r will be XOR with addr_offser, <=> haddr_r+addr_offset
//					why use the xor logic,not use the + ? 
//----------------------------------------------------//
//flash_addr 是一个byte的地址(AHB那边),要给FLash一个32bit地址(4byte),flash_addr_out要去掉地址低2位
//???这里flash_addr 有问题
//??不确定:prog_addr_r寄存器18bit有效?每一片是15bit,最高bit片选;一个byte的地址,最低2位没用。高16位有用,最高位选哪一个flash,中间15位位XYADR
//	如果是写FLash那么地址等于prog_addr,这个地址被配置在PROG_ADDR 寄存器中;
//	如果

assign flash_addr = (flash_prog_en) ? prog_addr_r :
					(boot_en && rd_main_sel)?{haddr[31:18],haddr[17:13]|addr_offset,haddr[12:0]}:haddr;
assign	flash_addr_out = flash_addr[16:2];

//flash_wdata 通过AHB写寄存器得到

assign flash_wdata = prog_data_r;

//------------------------------------------//
//config the flash configure register
//timing 都是通过hwdata写进来的
//-------------------------------------------//
//common configuration except for read operation

assign t_nvstr_setup 	= nvstr_setup_timing[11:0];
assign t_nvstr_hold 	= nvstr_hold_timing[11:0];
assign t_rcv 			= rcv_timing[7:0];

//program configuration
assign 	t_prog_setup 	= prog_setup_timing[15:0];
assign	t_prog_hold 	= progaddr_sethold_timing[3:0];
assign	t_addr_setup 	= progaddr_sethold_timing[7:4];
assign	t_addr_hold 	= progaddr_sethold_timing[11:8];
assign	t_prog_proc 	= progaddr_sethold_timing[15:0];

//read configuration
assign	t_addr_aces 	= rd_aces_timing[7:0];

//page erase timing
assign	t_page_erase 	= pe_timing[23:0];

//---------------------------------------------------//
//Generate flash reg_sel;infr_mem and main_mem sel when
//flash read operation
//main mem addr 	:0x0000_0000~0x0003_ffff
//infr mem addr 	:0x0006_1000~0x0006_7fff
//reg confige addr 	:0x0006_0000~0x0006_0fff
//Soc总线地址分配使用到 0x0028_1FFF  ,所以识别控制寄存器地址
//以及MAIN INFR 地址判断到24位[23:0] 
// REG  :	0x0006_0000~0x0006_0fff	:haddr[23:12] = 12'h060
// INFR :	0x0006_1000~0x0006_7fff :
// INFR :	0x0006_1000~0x0006_13ff    0110_0001_0000_0000
// INFR :	0x0006_1400~0x0006_17ff    0110_0100_0000_0000
//parameter	REG_ADDR	= 12'h060;	
//parameter	INFR_ADDR	= 12'h061;    ❓
//用地址的 haddr[11]判断INFR0,INFR1	
//parameter	INFR0_ADDR	= 1'h0;		
//parameter	INFR1_ADDR	= 2'h1;		
// MAIN	: 	0000_0000 ~ 0003_ffff	:haddr[23:15] = 6'h00
// MIAN0:	0000_0000 ~ 0001_ffff	:haddr[17:16] = 0-
// MIAN1:	0002_0000 ~ 0003_ffff	:haddr[17:16] = 1-
//parameter	MAIN_ADDR	= 6'h0;	
//用地址的 haddr[17]判断main0,main1	
//parameter	MAIN0_ADDR	= 1'b0;
//parameter	MAIN0_ADDR	= 1'b1;
//---------------------------------------------------//
assign reg_sel = (haddr_r[23:12] == REG_ADDR);

//area selected when in flash operation
assign rd_infr_sel 	= (haddr[23:12] == INFR_ADDR);
assign rd_infr0_sel = rd_infr_sel && (haddr[10] == INFR0_ADDR);
assign rd_infr1_sel = rd_infr_sel && (haddr[11:10] == INFR1_ADDR);
assign rd_main_sel 	= (haddr[23:18] == MAIN_ADDR);
assign rd_main0_sel = rd_mian_sel && (flash_addr[17] == MAIN0_ADDR);
assign rd_main1_sel = rd_mian_sel && (flash_addr[17] == MAIN1_ADDR);

assign flash0_rd_cs = (rd_infr0_sel || rd_main0_sel);
assign flash1_rd_cs = (rd_infr1_sel || rd_main1_sel);

//flash read operation enable
//读本来就要等所以这里没有打拍  f_rd_en中间信号,与flash_en作区分;
//读中断寄存器还是读存储器有区分,读存储器要等ready
assign f_rd_en = hsel && ((htrans == NONSEQ)||(htrans == SEQ)) && (!hwrite);
assign flash_rd_en = f_rd_en && ((!flash_busy)&&(flash0_rd_cs)||flash1_rd_cs);

//Generate boot protect signal.it actives "high" when boot begin and
//actives "low" when boot finish
assign boot_protect_n = boot_en;

//-------------------------------------------------------------//
//Generate boot area operation(write and page erase operation) enable signals
//when boot page erase (addr_offset_r == 5'h11111(8K bytes));
//			3e000-->page 496--->pe_num_r = 5'h11111;
//		16K bytes:
//			3c000-->page 480--->pe_num_r = 4'h1111;
//when boot write (addr_offset_r == 5'h11111(8K bytes));
//			3e000--> prog_addr_r[17:13] = 5'h11111;
//		16K bytes:
//			3c000--> prog_addr_r[17:14] = 4'h1111;
//-------------------------------------------------------------//
//一页4行,1行128byte,一页512byte;3c000-->page 480;3e000-->page 496
//写/页擦的地址刚好是boot区地址的话,boot写/页擦被选择
assign boot_wr_sel = (addr_offset_r == 5'b11111) ? (prog_addr_r[17:13] == 5'b11111 ):
					 (addr_offset_r == 5'b11110) ? (prog_addr_r[17:14] == 4'b1111 ): 1'b0;
assign boot_pe_sel = (addr_offset_r == 5'b11111) ? (pe_num_r[8:4] == 5'b11111 ):
					 (addr_offset_r == 5'b11110) ? (pe_num_r[8:5] == 4'b1111 ): 1'b0;

//select the right address when boot protect enable in the flash operation
//except the address of boot area 
//boot区没写,没页擦,boot区地址没有选中
assign non_boot_addr_correct = !(boot_wr_sel || boot_pe_sel);

//the adress is always right when boot protect turn off in flash
//operation or is part of right when address is not boot adress
//when boot prot turn on
//判断地址是否正确:启用了boot保护的话,non_boot_addr_correct要为1才正确
//即没有boot wr和pe;没启用boot保护,那么地址正确
assign flash_addr_correct = boot_protect_n ? 1'b1 : non_boot_addr_correct;

//generate one of conditions of flash program and page erase enable
//若地址不正确则不能进行写和页擦
assign wr_en = wr_en_r && flash_addr_correct;
assign pe_en = pe_en_r && flash_addr_correct;

//--------------------------------------------------//
//Generate flash control logic
//flash_prog_en :flash_wp_n = 1 && wr_en_r[0] = 1;
//flash_pe_en 	:flash_wp_n = 1 && pe_en_r[0] = 1;
//--------------------------------------------------//
//flash program operation enable
assign flash_prog_en = eflash_wp_n && (wr_en == 1'b1);

//area select when in flash page erase operation
//flash page erase operation enable
assign flash_pe_en = eflash_wp_n && (pe_en == 1'b1);

//pe_num_r和pe_main_infr_sel_r :配置寄存器,写入配置
assign pe_num = pe_num_r;
assign pe_main_infr_sel = pe_main_infr_sel_r;

//写状态寄存器有效:ahb写使能,配置寄存器选中,地址为状态寄存器地址
assign wr_status_valid = ahb_wr_en && reg_sel && (haddr_r[7:0] == FLASH_STATUS_ADDR);

//--------------------------------------------------------------//
//Generate interupt signal.
//when int_en_r[1] enable,flash_ctrl_int[i] output enable
//-------------------------------------------------------------//
assign flash_ctrl_int = (flash_status_r[0] && int_en_r[0] ||(flash_status_r[1]&&int_en_r[1])


//------------------------------------------------------//
//AHB read data output.   ✔
//hrdata = if(status_sel) flash_status_r
//			else (flash_cs) flash_rdata
//------------------------------------------------------//
//AHB读数据,当配置寄存器选中,读配置寄存器中内容,否则读flash读出的数据;

always@(*) begin
	if(ahb_rd_en && reg_sel)
	begin
		case(haddr_r[7:0])
			NVSTR_SETUP_ADDR		: hrdata = nvstr_setup_timing		 ;
			NVSTR_HOLD_ADDR			: hrdata = nvstr_hold_timing		 ;
			RCV_ADDR                : hrdata = rcv_timing				 ;
			PROG_SETUP_ADDR			: hrdata = prog_setup_timing		 ;
			PROGADDR_SETHOLD_ADDR	: hrdata = progaddr_sethold_timing	 ;
			PROG_PROC_ADDR          : hrdata = prog_proc_timing			 ;
			RD_ACES_ADDR            : hrdata = rd_aces_timing			 ;
			PE_ADDR                 : hrdata = pe_timing				 ;
			WR_EN_ADDR              : hrdata = {31'h0,wr_en_r}			 ;
			PE_CONFIG_ADDR          : hrdata = {31'h0,pe_en_r}			 ;
			PE_NUM_ADDR             : hrdata = {23'h0,pe_num_r}			 ;
			PE_MIANINFR_SEL_ADDR    : hrdata = {31'h0,pe_main_infr_sel_r};
			PROG_ADDR_ADDR          : hrdata = prog_addr_r               ;
			PROG_DATA_ADDR          : hrdata = prog_data_r               ;
			PROG_DATA1_ADDR         : hrdata = prog_data1_r              ;
			PROG_DATA2_ADDR         : hrdata = prog_data2_r              ;
			PROG_DATA3_ADDR         : hrdata = prog_data3_r              ;
			INT_EN_ADDR             : hrdata = int_en_r                  ;
			FLASH_STATUS_ADDR       : hrdata = {30'h0,flash_status_r}    ;
			BOOT_ERROR_ADDR         : hrdata = {31'h0,boot_pe_wr_error_r};
			default					: hrdata = 32'b0                     ;
		endcase
	end
	else
		hrdata = flash_rdata[31:0];
end

//--------------------------------------------------//
// Temp AHB addr and control signals  ✔
//--------------------------------------------------//
always@(posedge hclk or negedge hresetn) begin
	if(!hresetn) 
	begin
		hsize_r		<= 1'b0 ;
		htrans_r	<= 3'b0 ;
	    hburst_r	<= 3'b0 ;
        hwdata_r	<= 2'b0 ;
        haddr_r		<= 32'b0;
	end
	else if (hsel && hready_in)
	begin
		hsize_r		<= hsize	;
		htrans_r	<= htrans	;
	    hburst_r	<= hburst	;
        hwdata_r	<= hwdata	;
        haddr_r		<= haddr	;
	end
	else 
	begin
		hsize_r		<= 1'b0 ;
		htrans_r	<= 3'b0 ;
	    hburst_r	<= 3'b0 ;
        hwdata_r	<= 2'b0 ;
        haddr_r		<= 32'b0;	
	end
end

//----------------------------------------------------//
// Temp the value of addr_offset for boot area protect  ✔
//----------------------------------------------------//
always@(posedge hclk or negedge hresetn)
begin
	if(!hresetn)
		addr_offset_r <= 5'b0;
	else if (boot_en)
		addr_offset_r <= addr_offset;
end

//----------------------------------------------------------//
//when boot area protect,the program and page erase operation done
//signal will active high when boot area select and active low in the
//next clock    ✔
//用于硬件清零,done 信号只保持一个周期
//----------------------------------------------------------//
always@(posedge hclk or negedge hresetn)
begin 
	if (!hresetn)
	begin	
		boot_pe_done <= 1'b0;
		boot_wr_done <= 1'b0;
	end
	else if(boot_protect_n)
	begin
		boot_pe_done <= 1'b0;
		boot_wr_done <= 1'b0;	
	end
	else
	begin
		if (wr_en_r && boot_wr_sel)
			boot_wr_done <= 1'b1;
		else if (pe_en_r && boot_pe_sel)
			boot_pe_done <= 1'b1;
		else if (boot_wr_done || boot_pe_done) 
		begin
			boot_pe_done <= 1'b0;
			boot_wr_done <= 1'b0;
		end
	end
end

//-------------------------------------------------///
//AHB write registers.  
//when ahb_wr_en,hdata write into reg_address.
//----------------------------------------------------//
always@(posedge hclk or negedge hresetn)
begin
	if (!hresetn)
	begin
		nvstr_setup_timing		<= 32'h259	;	
	    nvstr_hold_timing		<= 32'h259  ;
	    rcv_timing				<= 32'h79   ;
	    prog_setup_timing		<= 32'h4b1  ;
	    progaddr_sethold_timing	<= 32'h333  ;
	    prog_proc_timing		<=	2'h962  ;
        rd_aces_timing          <= 32'h5    ;
        pe_timing               <= 32'h24a2c1;
		wr_en_r					<= 1'b0     ;
		pe_en_r                 <= 1'b0     ;
		pe_num_r                <= 9'h1df   ;
		pe_main_infr_sel_r      <= 1'b0     ;
		prog_addr_r             <= 32'h0    ;
		prog_data_r             <= 32'h0    ;
		int_en_r                <= 32'h0    ;
		invalid_data_r          <= 32'h0    ;
	end
	else if (ahb_wr_en && reg_sel)
	begin
		case(haddr_r[7:0])
			NVSTR_SETUP_ADDR		: nvstr_setup_timing		<= hwdata;	
			NVSTR_HOLD_ADDR			: nvstr_hold_timing			<= hwdata;	
			RCV_ADDR                : rcv_timing				<= hwdata;	
			PROG_SETUP_ADDR			: prog_setup_timing			<= hwdata;	
			PROGADDR_SETHOLD_ADDR	: progaddr_sethold_timing	<= hwdata;	
			PROG_PROC_ADDR          : prog_proc_timing			<= hwdata;	
			RD_ACES_ADDR            : rd_aces_timing			<= hwdata;	
			PE_ADDR                 : pe_timing					<= hwdata;	
			WR_EN_ADDR              : wr_en_r					<= hwdata[0];	//software set
			PE_CONFIG_ADDR          : pe_en_r                 	<= hwdata[0];
//最高位判断是flash0,还是flash1			
			PE_NUM_ADDR             : pe_num_r                	<= hwdata[8:0];	
			PE_MIANINFR_SEL_ADDR    : pe_main_infr_sel_r      	<= hwdata[0];	
			PROG_ADDR_ADDR          : prog_addr_r             	<= hwdata;	
			PROG_DATA_ADDR          : prog_data_r            	<= hwdata;
			PROG_DATA1_ADDR         : prog_data1_r            	<= hwdata;	
			PROG_DATA2_ADDR         : prog_data2_r            	<= hwdata;	
			PROG_DATA3_ADDR         : prog_data3_r            	<= hwdata;				
			INT_EN_ADDR             : int_en_r                	<= hwdata;	
			default					: invalid_data_r          	<= hwdata;		    
		endcase
	end
	else if (flash_prog_done || boot_wr_done)
	begin
		wr_en_r 	<= 1'b0;	//hardware reset,
		prog_addr_r <= 32'h3bfff;
	end
	else if (flash_pe_done || boot_pe_done)
	begin
		pe_en_r 	<= 1'b0;
		pe_num_r	<= 9'h1df;
	end
end

//----------------------------------------------------------------//
//Flash operation status and boot operation status
//flash_status_r:页擦写操作完成信号  ✔
//----------------------------------------------------------------//
always@(posedge hclk or negedge hresetn)
begin
	if (!hresetn)
		flash_status_r[0] <= 1'b0;
	else if (wr_status_valid && hwdata[0]) //software :wite operation to reset;write 1 to reset
		flash_status_r[0] <= 1'b0;
	else if (flash_prog_done || boot_wr_done)
		flash_status_r[0] <= 1'b1;	//hardware set,when to reset? -->status
end

always@(posedge hclk or negedge hresetn)
begin
	if (!hresetn)
		flash_status_r[1] <= 1'b0;
	else if (wr_status_valid && hwdata[1]) //software :wite operation to reset;write 1 to reset
		flash_status_r[1] <= 1'b0;
	else if (flash_pe_done || boot_pe_done)
		flash_status_r[1] <= 1'b1;	//hardware set,when to reset? -->status
end

//----------------------------------------------------------------//
//Flash operation status and boot operation status
//boot_pe_wr_error_r:boot区非法操作
//启动了boot区保护boot_pe_sel/boot_wr_sel确有效     ✔

always@(posedge hclk or negedge hresetn)
begin
	if (!hresetn)
		boot_pe_wr_error_r <= 1'b0;
	else if (boot_protect_n) 
		boot_pe_wr_error_r <= 1'b0;
	else if (wr_status_valid && (hwdata[0]||hwdata[1]))
		boot_pe_wr_error_r <= 1'b0;
	else if (boot_pe_sel || boot_wr_sel)
		boot_pe_wr_error_r <= 1'b1;	
end


endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值