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

基于AHB_BUS的eFlash控制器RTL的更多相关文章

  1. 基于Controller接口的控制器及简单应用

    DispatcherServlet在Spring当中充当一个前端控制器的角色,它的核心功能是分发请求.请求会被分发给对应处理的Java类,Spring MVC中称为Handle.在Spring 2.5 ...

  2. Android 基于蓝牙的方向控制器

    最近开发了一个蓝牙控制器App,用手机远程控制小球的运动. 包含了一些基础知识:多线程使用,页面UI数据更新,按钮事件,选择项功能,蓝牙功能(蓝牙打开,蓝牙搜索,蓝牙连接,蓝牙命令发送,蓝牙命令接收) ...

  3. 基于S5PC100的FIMC控制器解析

    作者:邹南,华清远见嵌入式学院讲师. http://www.cnblogs.com/gooogleman/archive/2012/07/26/2610449.html CAMERA SENSOR O ...

  4. 基于异步的MVC webAPI控制器

    MVC – Task-based Asynchronous Pattern (TAP) – Async Controller and SessionLess Controller Leave a re ...

  5. 在MVC控制器里面使用dynamic和ExpandoObject,实现数据转义的输出

    在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计的时候考虑周到外,还需要考虑数据展现的处理.如果是常规的处理,那 ...

  6. MVC控制器里面使用dynamic和ExpandoObject

    MVC控制器里面使用dynamic和ExpandoObject 在很多时候,我们在数据库里面定义表字段和实际在页面中展示的内容,往往是不太匹配的,页面数据可能是多个表数据的综合体,因此除了我们在表设计 ...

  7. angular控制器、服务和指令三者之间的关系

    从总体来看,这三个组件的关系如下所示: 服务负责从远端服务器抓取和存储数据. 基于服务构建的控制器将为angular的作用域层次提供数据和功能. 基于服务和控制器构建的指令将直接与文档对象模型(DOM ...

  8. AngularJs开发——指令与控制器间的通信

    (原文:http://www.html5jscss.com/controller-between-directive.html) 指令与控制器之间通信,跟控制器间的通信.指令间通信也类似,也是下几种方 ...

  9. laravel控制器之资源控制器

    资源控制器 Laravel 的资源控制器可以让我们很便捷地构建基于资源的 RESTful 控制器,例如,你可能想要在应用中创建一个控制器,用于处理关于文章存储的 HTTP 请求,使用 Artisan ...

  10. 基于SSM的Java Web应用开发原理初探

    SSM开发Web的框架已经很成熟了,成熟得以至于有点落后了.虽然如今是SOA架构大行其道,微服务铺天盖地的时代,不过因为仍有大量的企业开发依赖于SSM,本文简单对基于SSM的Java开发做一快速入门, ...

随机推荐

  1. 常用API之IP定位地区

    常用API之IP定位地区 高德地图API https://lbs.amap.com/api/webservice/guide/api/ipconfig 百度地图API https://lbsyun.b ...

  2. C语言汉诺塔递归算法实现

    这是个目录 一.什么是递归函数 1.先看一下一个递归的例子 2.递归的基本原理 二.汉诺塔问题 1.简要概括一下汉诺塔的故事 2.回到编程,汉诺塔问题主要就是解决这个问题: 3.怎么解决汉诺塔问题 要 ...

  3. GeoServer发布地图服务(WMS、WFS)

    目录 1. 概述 2. 矢量数据源 3. 栅格数据源 1. 概述 我们知道将GIS数据大致分成矢量数据和栅格数据(地形和三维模型都是兼具矢量和栅格数据的特性).但是如果用来Web环境中,那么使用图片这 ...

  4. kubernetes安装(一)

    参考: https://www.cnblogs.com/liuyangQAQ/p/17299871.html 部署组件包 名称 安装包 kubeadm集群组件 kubelet-1.20.9 kubea ...

  5. P4928 [MtOI2018]衣服?身外之物! 题解

    题意 gcd 共有 \(n\) 件衣服,编号为 \(A_1,A_2,\cdots A_n\). 每一件衣服分别拥有颜色值和清洗时间,他在每一件衣服穿完以后都会将其送去清洗,而这件衣服当天所拥有的舒适感 ...

  6. 【独立闯天下】Prim新传奇!💥原团队的Blazor版本迟迟无音,合并请求石沉大海。于是,我们决定单干!加入Prime Blazor版项目,一起开创崭新的旅程吧!🌟📚

    共建Prime的Blazor版:为开源社区注入新活力 Prime组件库作为一款广受欢迎的开源组件库,一直以来都备受开发者们的青睐.然而,随着技术的不断发展和更新,原团队的Blazor版本似乎已经逐渐失 ...

  7. VSCode C++开发环境配置: LLVM clang clangd

    工欲善其事,必先利其器 llvm/clang 比 VSCode 自带的代码提示功能速度更快,功能更强(支持 clang-tidy). 安装 llvm.clang sudo apt install ll ...

  8. 2、Text组件详解

    TextStyle 的参数 //代码块 importM import 'package:flutter/material.dart'; void main() { runApp(MaterialApp ...

  9. MySQL进阶篇:详解存储引擎InnoDB

    本篇基础环境是使用navicat 12和Mysql8.0 MySQL进阶篇:第一章_一.二_存储引擎特点_InnoDB 1.1 存储引擎特点 1.1.1 InnoDB 1). 介绍 InnoDB是一种 ...

  10. Kubernetes的拐点助推器:左手开源,右手边缘计算

    摘要:KubeEdge 是首个基于 Kubernetes 扩展的,提供云边协同能力的开放式智能边缘计算平台,也是 CNCF 在智能边缘领域的首个正式项目.依托 Kubernetes 强大的容器编排和调 ...