基于AHB_BUS的eFlash控制器RTL

eFlash控制器的RTL

gvim 操作

  • gg -- 跳到首页
  • GG -- 按住shift,跳到尾部
  • ctrl+V --> 上下键选择行 --> shift+i -->输入 -->esc退出 -- 实现列操作
  • u -- 撤销操作
  • . -- 重复上一次操作
  • v/flash/d -- 删除有flash的行
  • g/flash/d -- 保留有flash的行
  • cw -- 删除原来的word进入insert,替换原来的word -- 用点进行重复操作
  • shift+v -- 进入visual lines模式 -- >选择行 --> y复制 --> 移动光标 p复制,8p复制8份

flash_ahb_slave_if

// flash_ahb_slave_if

module flash_ahb_slave_if(
	
	//********************************************************
	//                  input signals                       //
	//********************************************************
	
	// ahb signals
	hclk,
	hresetn,
	hsel,
	hready_in,
	hwrite,
	hsize,
	htrans,
	hburst,
	hwdata,
	haddr,
	
	
	// flash_ctrl input signals
	flash_rdata,
	flash_prog_done,
	flash_pe_done,
	flash_busy,
	
	// 外部输入的擦写保护信号
	eflash_wp_n,
	
	// boot 区间的初始地址,外部输入信号
	addr_offset, 
	
	// boot 使能信号
	boot_en,
	
	// read操作的时候通过hready拉低实现
	hready_flag,
	
	//********************************************************
	//                  output signals                      //
	//********************************************************
	
	// *************************输出读写擦使能信号*************************
	
	flash_prog_en,
	flash_pe_en,
	flash_rd_en,
	
	// *******************读写擦flash中哪部分对应的信号********************
	// flash片选信号
	// information or main block选择信号

	
	// 读flash0或者flash1
	flash0_rd_cs
	flash1_rd_cs
	
	// 读flash中的哪部分,代码有冗余
	rd_infr0_sel,
	rd_infr1_sel,
	rd_main0_sel,
	rd_main1_sel,
	
	// 写flash中的哪部分
	prog_infrarea0_sel,
	prog_infrarea1_sel,
	prog_mainarea0_sel,
	prog_mainarea1_sel,
	
	// 擦除的页数
	pe_num,
	
	// 擦除flash中的哪部分
	pe_main_infr_sel,
	
	// *******************读写地址和数据********************
	flash_addr_out,
	flash_wdata,
	
	
	
	
	// ******************时间寄存器配置信号*****************
	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,
	
	
	// *****************中断信号****************************
	flash_ctrl_int
	
	
);


	input clk;
	input hresetn;
	input hsel;
	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;
	
	input flash_prog_done;
	input flash_pe_done;
	input flash_busy;
	
	// 0的时候擦写保护,1的时候不保护
	input eflash_wp_n;
	input boot_en;
	input [4:0] addr_offset;
	input hready_flag;
	
	output flash_prog_en;
	output flash_pe_en;
	output flash_rd_en;
	
	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;
	
	
	output flash0_rd_cs
	output flash1_rd_cs

	output rd_infr0_sel,
	output rd_infr1_sel,
	output rd_main0_sel,
	output rd_main1_sel,

	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;
	output [14:0] flash_addr_out;
	output [31:0] flash_wdata;



	//********************************************************
	//                 internal register                    //
	//********************************************************
	
	// register used for temp the ahb input signals
	reg hwrite_r;
	reg [2:0] hsize_r;
	reg [2:] hburst_r;
	reg [1:0] htrans_r;
	reg [31:0] haddr_r;
	
	// flash operation config registers
	// 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] prog_hold_timing;
	reg [31:0] prog_proc_timing;
	reg [31:0] progaddr_sethold_timing;
	
	// read timing 
	reg [31:0] rd_aces_timing;
	
	// erase timing
	reg [31:0] pe_timing;
	
	// Address register and program 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] invalid_data_r;
	
	// flash program/page erase operation control registers and main  mem/info mem/info
	// selected mark
	// wr_en_r[0]:flash prog enable
	// pe_en_r[0]:flash pe enable
	reg wr_en_r;
	reg pe_en_r;
	reg pe_main_infr_sel_r;
	reg [8:0] pe_num_r;
	
	// int_en_r for enable interrupt and flash operation(prog/pe) status
	reg [31:0] int_en_r;
	reg [1:0] flash_status_r;
	
	// boot_pe_wr_error_r:boot area page erase or write finish forbidden when boot area protected
	reg boot_pe_wr_error_r;
	
	reg boot_pe_done; // This two signals show boot operation
	reg boot_wr_done; // finish when in boot area protect
	
	
	reg [4:0] addr_offset_r; // 16k bytes boot area
	reg [31:0] hrdata;
	
	
	wire ahb_wr_en;
	wire ahb_rd_en;
	wire trans_en;
	wire f_rd_en;
	wire wr_status_valid;
	wire rd_infr_sel;
	wire rd_main_sel;
	
	// flash operation area select
	wire reg_sel;
	wire rd_infrarea_sel;
	wire rd_mainarea_sel;
	wire prog_pe_infrarea_sel;
	wire prog_pe_mainarea_sel;
	wire infrarea_sel;
	wire flash_mem_rd;
	wire [31:0] flash_addr;
	
	// boot area operation enable signals
	
	wire boot_protect_n;
	wire boot_pe_sel;
	wire boot_wr_sel;
	wire non_boot_addr_correct;
	wire flash_addr_correct;
	wire wr_en;
	wire pe_en;
	
	
	// AHB Bus transactions
	parameter		IDLE 	=	2'b00,
					BUSY 	=	2'b01,
					NONSEQ 	=	2'b10,
					SEQ 	=	2'b11;
					
	
	// flash 中的 寄存器空间
	parameter		REG_ADDR	=	12'h060; // 60000 - 60fff
	parameter		INFR_ADDR	=	12'h061; // 61000 - 617ff
	parameter		INFR0_ADDR	=	1'b0;    // 61000 - 613ff
	parameter		INFR1_ADDR	=	2'h1;    // 61400 - 617ff
	parameter		MAIN_ADDR	=	6'h0;    // 0000_0000 - 0003_ffff
	parameter		MAIN0_ADDR	=	1'b0;    // 0000_0000 - 0001_ffff: haddr[17:16] = 0
	parameter		MAIN1_ADDR	=	1'b1;    // 0002_0000 - 0003_ffff: haddr[17;16] = 1
	
	
	
	
	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_MAININFR_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;
	
	
	
	//------------------------------------------------------------//
	// Generate AHB slave output signals : hready_out & hresp
	// flash pe : hready_out = 1
	// flash read : if(reg operation) hready_out = 1
	//              else hready_out = flash_rd_ready
	// -----------------------------------------------------------//
	
	assign hready_out = hready_flag;
	
	assign hresp = 2'b0;
	
	
	//--------------------------------------------//
	// Generate ahb wirte and read enable signals //
	// ahb_wr_en: htrans_r and hwrite_r
	// ahb_rd_en:htrans_r and hwrite_r
	
	assign ahb_wr_en = (htrans == NONSEQ || htrans == SEQ) && hwrite_r && (!flash_busy);
	
	// read的时候不用与上flash_busy,因为hready已经进行了判断

	
	//--------------------------------------------//
	// flash input data and address
	// flash_addr : haddr_r[17:2] => 64Kbytes row address
	// flash_addr_out : haddr_r[17:2] => double word (32bit) align
	// flash_wdata:when prog,prog_data_r
	// Note: haddr_r willbe xor with addr_offset <=> haddr_r + addr_offset
	// why use the xor logic,not use + ?
	//--------------------------------------------//
	
	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;
						
	// flash_addr是以byte的地址,但是在prog和read的时候是以dw为单位的地址,所以进行转换,去掉低两bit
	// xaddr - 10bit
	// yaddr - 5bit
	// flash_addr_out => 15bit
	assign flash_addr_out = flash_addr[16:2];
	
	// ahb写寄存器得到寄存器的值
	assign flash_wdata = prog_data_r;
	
	//--------------------------------------------//
	//     Confige the flash configure registers  //
	//--------------------------------------------//
	// 将寄存器的值连出来
	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 = prog_proc_timing[15:0]
	
	// read configuration
	assign t_addr_aces = rd_aces_timing[7:0];
	
	// page erase configuration
	assign t_page_erase = pe_timing[23:0];
	
	//----------------------------------------------------------------------------//
	// Generate flash control logic
	// flash_prog_en :	eflash_wp_n = 1 && wr_en_r[0] = 1;
	// flash_pe_en :	eflash_wp_n = 1 && wr_en_r[0] = 1;
	// ---------------------------------------------------------------------------//
	
	//----------------------------------------------------------------------------//
	// Generate flash reg_sel : infr_mem and main_mem sel when flash read operation
	// main mem addr: 	 0x0000 0000 - 0x 0003 ffff (18bit - 256K)
	// infr mem addr:	 0x0006 1000 - 0x 0006 7fff (15bit - 32K)
	// reg config addr	 0x0006 0000 - 0x 0006 0fff (12bit - 4k)
	//----------------------------------------------------------------------------//
	
	// 寄存器空间4k
	// 0x0006 0000 - 0x 0006 0fff 
	// 只需要判断haddr[23:12]这个范围,就可以判断出访问的是哪个空间
	// 060 -- 0000 0110 0000 -- REG_ADDR
	assign reg_sel = haddr_r[23:12] == REG_ADDR;
	
	
	// area select when in flash read operation
	// information block 2 page -- 1k -- 10bit(0-9,用第11bit选择哪一个infr)
	// 2 information block 2k - 11bit
	// 0x0006 1000 - 0x0006 17ff
	// 061 -- 0000 0110 0001 -- INFR_ADDR
	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);
	
	// 低18bit为256Kflash的寻址,23-18bit用于寻址main block
	// 128K -- 17bit,可以用18bit选择哪个flash的main block
	assign rd_main_sel = (haddr[23:18] == MAIN_ADDR);
	assign rd_main0_sel = rd_main_sel && (flash_addr[17] == MAIN0_ADDR);
	assign rd_main1_sel = rd_main_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 ctrl的读请求
	// flash_rd_en - 对于flash的读请求,只有当选择读取main block的时候才会产生对flash的读请求
	// flash_busy - 当前flash正处于读写擦状态,不能进行操作
	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
	// boot_en为高的时候需要对于boot区间进行保护
	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 byte));
	// 					    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(8 kbytes)):
	//						3e000-->prog_addr_r[17:13] = 5'h111111;
	//						16k bytes:
	//						3c000-->prog_addr_r[17:14] = 4'h1111;
	// -------------------------------------------------------------------------//
	
	// boot区间有两种情况
	// 8k以3e000为offset
	// 16k 以3c000为offset
	// 根据addr_offset判断是3c000开始还是3e000开始
	// 3c000 - 3ffff -- 16k
	// 3e000 - 3ffff -- 8K
	
	// 3e000 -- 0011 1110 0000 0000 0000 - 低13bit表示boot区的粒度,高5bit表示offset地址
	// 3c000 -- 0011 1100 0000 0000 0000
	// 3ffff -- 0011 1111 1111 1111 1111
	
	// for program
	// addr_offset == ox3e000;
	// boot area :
	// first_addr:	0011 1111 0000 0000 0000 
	// last_addr:	0011 1111 1111 1111 1111
	
	// addr_offset == ox3c000;
	// boot area :
	// first_addr:	0011 1110 0000 0000 0000 
	// last_addr:	0011 1111 1111 1111 1111
	
	// for erase
	// page - 512byte -- 9bit表示
	// addr_offset == ox3e000;
	// boot area :
	// first_page:	0011 1111 000
	// last_addr:	0011 1111 111
	
	// addr_offset == ox3c000;
	// boot area :
	// first_page:	0011 1110 000
	// last_page:	0011 1111 111
	
	// 判断擦写是不是落在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) ? (page_num_r[8:4] == 5'b11111):
							(addr_offset_r == 5'b11110) ? (page_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
	// non_boot_addr_correct -- 表示当前不是非法操作
	assign non_boot_addr_correct = !(boot_wr_sel || boot_pe_sel);
	
	
	// The address is always right when boot protect  turn off in flash operation
	// or is part of right when the address is not boot Address when boot protect turn on
	assign flash_addr_correct = boot_protect_n ? 1'b1 : non_boot_addr_correct;
	
	// Generate one of condition of flash program and page erase enable
	// 擦写寄存器中的值为高并且flash地址选择正确,产生擦写信号
	assign wr_en = wr_en_r && flash_addr_correct;
	assign pe_en = pe_en_r && flash_addr_correct;
	
	// flash program operation enable
	// flash_prog_en - 给到状态机
	// eflash_wp_n 为0 ,写保护信号有效,flash_prog_n 永远为0,进行写保护
	// eflash_wp_n 为1,撤销写保护,wr_en == 1'b1,产生写使能给状态机
	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_page_erase = eflash_wp_n && (pe_en == 1'b1);
	assign pe_num = pe_num_r;
	assign pe_main_infr_sel = pe_main_infr_sel_r;
	
	
	//area select when in flash program operation
	assign prog_infrarea_sel = (prog_addr_r[23:12] == INFR_ADDR);
	assign prog_infrarea0_sel = prog_infrarea_sel && (prog_addr_r[10] == INFR0_ADDR);
	assign prog_infrarea1_sel = prog_infrarea_sel && (prog_addr_r[11:10] == INFR1_ADDR);
	
	// 低18bit为256Kflash的寻址,23-18bit用于寻址main block
	// 128K -- 17bit,可以用18bit选择哪个flash的main block
	assign prog_mainarea_sel = (prog_addr_r[23:18] == MAIN_ADDR);
	assign prog_mainarea0_sel = prog_mainarea_sel && (prog_addr_r[17] == MAIN0_ADDR);
	assign prog_mainarea1_sel = prog_mainarea_sel && (prog_addr_r[17] == MAIN1_ADDR);
	
	
	//--------------------------------------------------------------//
	// Generate interrupt signal.
	// When int_en_r[i] enable,flash_ctrl_int[i] output
	// enable
	//--------------------------------------------------------------//
	assign wr_status_valid = ahb_wr_en && reg_sel && (haddr_r[7:0] == FLASH_STATUS_ADDR);
	
	// flash_status_r[0]为高,表示有写操作完成
	// int_en_r[0] 为高表示写操作中断使能,可以发出中断
	// flash_status_r[1]为高,表示有pe操作完成
	// int_en_r[1] 为高表示pe操作中断使能,可以发出中断
	assign flash_ctrl_int = ((flash_status_r[0]) && int_en_r[0]) || (flash_status_r[1]) && int_en_r[1];
	
	//--------------------------------------------------------------//
	// Temp AHB addr and control signals
	//--------------------------------------------------------------//
	
	always @ (posedge hclk or negedge hresetn)
	begin
		if(!hresetn) begin
			hwrite_r <= 1'b0;
			hsize_r <= 3'b0;
			htrans_r <= 2'b0;
			haddr_r <= 32'b0;
			hburst_r <= 3'b0;
		else if(hsel && hready_in) begin
			hwrite_r <= hwrite;
			hsize_r  <= hsize ;
			htrans_r <= htrans;
			haddr_r  <= haddr ;
			hburst_r <= hburst;	
		end
		else begin
			hwrite_r <= 1'b0;
			hsize_r <= 3'b0;
			htrans_r <= 2'b0;
			haddr_r <= 32'b0;
			hburst_r <= 3'b0;
		end
	end
	end
	
	
	// ---------------------------------------------------------------//
	// ahb read data output 
	// ahb总线读数据的产生
	always @ (*)
	begin
		if(ahb_rd_en && reg_sel)
		begin
			case(haddr[7:0])
				NVSTR_SETUP_ADDR		:	hrdata = nvstr_setup_timing;
				NVSTR_HOLD_ADDR			:	hrdata = hvstr_hold_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;
				RCV_ADDR				:	hrdata = rcv_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_MAININFR_SEL_ADDR	:	hrdata = {31'h0,pe_main_infr_sel_r};
				PE_ADDR					:	hrdata = pe_timing;
				PROG_ADDR_ADDR			:	hrdata = prog_addr_r;
				PROG_DATA_ADDR			:	hrdata = prog_data_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 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
	//-------------------------------------------------------------------------//
	
	// 擦写使能并且选择boot区间会将boot_wr/pe_done信号拉高
	// boot_wr/pe_done -- 信号拉高之后会写状态寄存器
	always @(posedge hclk or negedge hresetn)
	begin
		if(!hresetn) begin
			boot_wr_done <= 1'b0;
			boot_pe_done <= 1'b0;
		end
		else if(boot_protect_n) begin // boot_en失效的条件下
			boot_wr_done <= 1'b0;
			boot_pe_done <= 1'b0;
		end
		else if(wr_en && boot_wr_sel)
			boot_wr_done <= 1'b1;
		else if(pe_en && boot_pe_sel)
			boot_pe_done <= 1'b1;
		else if(boot_wr_done || boot_pe_done) begin 
			boot_wr_done <= 1'b0;
		    boot_pe_done <= 1'b0;
		end
	end
	
	
	
	//-------------------------------------------------------------------------//
	// AHB write registers
	// When ahb_wr_en,hwdata 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		<=	32'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;
				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;
				RCV_ADDR				:	rcv_timing				<=	 hwdata;
				WR_EN_ADDR				:	wr_en_r					<=	 hwdata[0];
				PE_CONFIG_ADDR			:	pe_en_r					<=	 hwdata[0];
				PE_NUM_ADDR				:	pe_num_r				<=	 hwdata[8:0];
				PE_MAININFR_SEL_ADDR	:	pe_main_infr_sel_r		<=	 hwdata[0];
				PE_ADDR					:	pe_timing				<=	 hwdata;
				PROG_ADDR_ADDR			:	prog_addr_r				<=	 hwdata;
				PROG_DATA_ADDR			:	prog_data_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
			// flash_prog_done - 是flash ctrl返回的信号
			// boot_wr_done - 是boot使能时,写boot区返回的信号
			wr_en_r <= 1'b0;
			prog_addr_r <= 32'h3bfff;
		end
		else if(flash_pe_done || boot_pe_done)
			pe_en_r <= 1'b0;
			pe_num_r <= 9'h1df;
		end
			
	end
	
	
	//-------------------------------------------------------------------------//
	// Flash operation status and boot operation status. 
	//-------------------------------------------------------------------------//
	always @ (posedge hclk or negedge hresetn)
	begin
		if(!hresetn) begin
			// 第一bit表示写状态
			flash_status_r[0] <= 1'b0;
		end 
		else if(wr_status_valid && hwdata[0]) begin  // 软件清0 - 写1清0
			flash_status_r[0] <= 1'b0;
		end
		else if(flash_prog_done || boot_wr_done)     // 硬件置位
			flash_status_r[0] <= 1'b1;
	end
	
	// flash_status_r 第一bit表示wr状态
	// 第二bit表示pe的状态-- 是否完成
	always @ (posedge hclk or negedge hresetn)
	begin
		if(!hresetn) begin
			// 第一bit表示写状态
			flash_status_r[1] <= 1'b0;
		end 
		else if(wr_status_valid && hwdata[1]) begin  // 软件清0 -- 写1清0(寄存器的值不一定为1)
			flash_status_r[1] <= 1'b0;
		end
		else if(flash_pe_done || boot_pe_done)     // 硬件置位
			flash_status_r[1] <= 1'b1;
	end
	
	always @ (posedge hclk or negedge hresetn)
	begin
		if(!hresetn) begin
			// 第一bit表示写状态
			boot_pe_wr_error_r <= 1'b0;
		end 
		else if(boot_protect_n) begin  
			boot_pe_wr_error_r <= 1'b0;
		end
		else if(wr_status_valid && (hwdata[1]||hwdata[0])) begin
			boot_pe_wr_error_r <= 1'b0;
		end
		else if(boot_pe_sel || boot_wr_sel)     
			boot_pe_wr_error_r <= 1'b1;
	end
	
endmodule
posted @ 2023-05-28 04:22  Icer_Newer  阅读(257)  评论(0编辑  收藏  举报