📄 adv_bb.v
字号:
endcase end //default endcase end //ifend //always (predecode)//// Command Decode//always @(DataPtr) begin : command integer BlockUsed; // When DataPtr hits zero it means that all the // additional data has been given to the current command if (!Reset && (DataPtr == 0) && (WriteToPtr != `NewCmd)) begin if (CmdValid && (WriteToPtr == `CmdField)) begin WriteToPtr = `NewCmd; // Just finish a multi-cycle command. Determine which block the command uses BlockUsed = -1; for (LoopCntr = `NumberOfBlocks-1; LoopCntr >= 0; LoopCntr = LoopCntr - 1) begin if (Cmd[`CmdAdd_1] <= BlocksEnd[LoopCntr]) BlockUsed = LoopCntr; end if (BlockUsed == -1) $display("FLASH: Error: Invalid Command Address"); else Cmd [`OpBlock] = BlockUsed; if (Cmd [`OpType] == `Erase ) begin if (BlocksType[BlockUsed] == `MainBlock) Cmd[`Time] = Main_Erase_Time; else Cmd[`Time] = Param_Erase_Time; end else if (Cmd [`OpType] == `Program) Cmd[`Time] = Program_Time_Word; else Cmd[`Time] = 0; // If this command needs a confirm // (flaged at predecode) then check if confirm was received if (Cmd [`Confirm]) begin if (Cmd[`CmdData1Fx8] == `ConfirmCmd) begin // If the command is still valid put it in the queue and deactivate the array Algorithm = Cmd; AlgTime = Cmd [`Time] ; CmdValid <= `FALSE; if (!VppError) ReadyBusy <= #1 `Busy; ReadMode <= `rdCSR; end else begin ReadMode <= `rdCSR ; ProgramError <= `TRUE; EraseError <= `TRUE; CmdValid <= `FALSE; end end else begin Algorithm = Cmd; AlgTime = Cmd [`Time] ; CmdValid <= `FALSE; if (!VppError) ReadyBusy <= #1 `Busy ; ReadMode <= `rdCSR; end end endend //always (command)//////////////// Execution ////////////////always @(posedge AlgDone) begin : execution if (!Reset) begin if (AlgDone) begin // When the algorithm finishes // if chips is executing during an erase interrupt // then execute out of queue slot 2 if (Algorithm [`OpType] == `Erase) begin // ERASE COMMAND // if (VppFlag) begin VppError <= `TRUE ; EraseError <= `TRUE; end else begin // Do ERASE to OpBlock if ((BlocksType[Algorithm[`OpBlock]] == `LockBlock) && !InternalBoot_WE) begin $display("FLASH: Error: Attempted to erase locked block."); EraseError <= `TRUE; BlockLockStatus <= `TRUE; end else begin for (LoopCntr = BlocksBegin[Algorithm[`OpBlock]]; LoopCntr <= BlocksEnd[Algorithm[`OpBlock]]; LoopCntr = LoopCntr + 1) MainArray [LoopCntr] = 'hFFFF; BlocksEraseCount[Algorithm[`OpBlock]] = BlocksEraseCount[Algorithm[`OpBlock]] + 1; $display("FLASH: Block %d Erase Count: %d",Algorithm[`OpBlock],BlocksEraseCount[Algorithm[`OpBlock]]); end end end else begin // PROGRAM COMMAND // if (VppFlag) begin ProgramError <= `TRUE; VppError <= `TRUE ; end else begin if ((BlocksType[Algorithm[`OpBlock]] == `LockBlock) && !InternalBoot_WE) begin $display("FLASH: Error: Attempted to program locked boot block."); ProgramError <= `TRUE; BlockLockStatus <= `TRUE; end else begin Program (MainArray[Algorithm [`CmdAdd_1]], Algorithm [`CmdData_1]); if (EraseSuspended == `TRUE) begin AlgTime = TimeLeft; ToBeSuspended = `Erase; Algorithm = SuspendedAlg; end end end end end //if (AlgDone) ReadyBusy <= `Ready; end //if (!Reset)end //always (execution)always @(ReadyBusy) begin if ((!Reset) && (ReadyBusy == `Busy)) begin // If the algorithm engine // just started, start the clock ClearVppFlag <= #1 `TRUE ; ClearVppFlag <= #3 `FALSE ; TimerClk <= #1 1'b1 ; TimerClk <= #TimerPeriod 1'b0 ; end end// record the time for addr changes .always @(addr) begin if ($time != 0 & !ceb) begin if (((curr_addr_time + TAVAV) > $time) & !ceb) //Read/Write Cycle Time --- Added "& !ceb" RU 9/9/99 9pm $display("FLASH: [",$time,"] Timing Violation: Read/Write Cycle Time (TAVAV), Last addr change: %d",curr_addr_time) ; curr_addr_time = $time ; endend// record the time for oe changes .always @(oeb) begin if ($time != 0) begin curr_oe_time = $time ; endend// record the time for ce changes .always @(ceb) begin if ($time != 0) begin curr_ce_time = $time ; endendreg rpb_r;initial rpb_r = rpb;// record the time for rp changes .always @(rpb) begin if ((rpb_r != rpb) & ($time != 0) ) begin curr_rp_time = $time ; rpb_r = rpb; endend// record the time for ReadMode changes .always @(ReadMode) begin if ($time != 0) begin curr_ReadMode_time = $time ; endend// record the time for Internal_RE changes .always @(Internal_RE) begin if ($time != 0) begin curr_Internal_RE_time = $time ; endendalways @(InternalBoot) begin InternalBoot_WE <= #TVPWH InternalBoot;endalways @(TimerClk) begin if ((!Reset) && (ReadyBusy == `Busy) && (TimerClk == 1'b0)) begin // Reschedule clock and // decrement algorithm count TimerClk <= #1 1'b1 ; TimerClk <= #TimerPeriod 1'b0 ; if (Suspend) begin // Is the chip pending suspend? If so do it Suspend = `FALSE; if (ToBeSuspended == `Program) begin WriteSuspended <= #Program_Suspend_Time `TRUE; ReadyBusy <= #Program_Suspend_Time `Ready; end else begin EraseSuspended <= #Erase_Suspend_Time `TRUE; ReadyBusy <= #Erase_Suspend_Time `Ready; end end if (ReadyBusy == `Busy) begin AlgTime = AlgTime - 1; if (AlgTime <= 0) begin // Check if the algorithm is done AlgDone <= #1 `TRUE ; AlgDone <= #10 `FALSE ; end end end end //------------------------------------------------------------------------// Reset Controller//------------------------------------------------------------------------always @(rpb or vcc) begin : ResetPowerdownMonitor // Go into reset if reset powerdown pin is active or // the vcc is too low if ((rpb != `VIH) || (vcc < 2500)) begin // Low Vcc protection Reset <= `TRUE ; if (!((vcc >= 2500) || StartUpFlag)) $display ("FLASH: Low Vcc: Chip Resetting") ; end else // Coming out of reset takes time Reset <= #TPHWL `FALSE ;end//------------------------------------------------------------------------// VccMonitor//------------------------------------------------------------------------always @(Reset or vcc) begin : VccMonitor// Save the array when chip is powered off if ($time > 0) begin if (vcc == 0 && SaveOnPowerdown) StoreToFile; if (vcc < 2700) $display("FLASH: Vcc is below minimum operating specs"); else if ((vcc >= 2700) && (vcc <= 3600) && (`VccLevels & `Vcc2700)) begin //$display ("Vcc is in operating range for 2.7 volt mode") ; // Commented out RU 9/11/99/* TAVAV = `TAVAV_27; TAVQV = `TAVQV_27; TELQV = `TELQV_27; TPHQV = `TPHQV_27; TGLQV = `TGLQV_27; TELQX = `TELQX_27; TEHQZ = `TEHQZ_27; TGLQX = `TGLQX_27; TGHQZ = `TGHQZ_27; TOH = `TOH_27 ; TPHWL = `TPHWL_27; TWLWH = `TWLWH_27; TDVWH = `TDVWH_27; TAVWH = `TAVWH_27; TWHDX = `TWHDX_27; TWHAX = `TWHAX_27; TWHWL = `TWHWL_27; TVPWH = `TVPWH_27;*/ if ((vpp <= 3600) && (vpp >= 2700)) begin Param_Erase_Time = `AC_EraseTime_Param_27_27; Main_Erase_Time = `AC_EraseTime_Main_27_27; Program_Time_Word = `AC_ProgramTime_Word_27_27; end else begin Param_Erase_Time = `AC_EraseTime_Param_27_12; Main_Erase_Time = `AC_EraseTime_Main_27_12; Program_Time_Word = `AC_ProgramTime_Word_27_12; end end else $display ("FLASH: Vcc is out of operating range") ; end //$timeend//------------------------------------------------------------------------// VppMonitor//------------------------------------------------------------------------always @(VppFlag or ClearVppFlag or vpp) begin : VppMonitor if (ClearVppFlag) begin VppErrFlag = `FALSE ; end else if (!(((vpp <= 12600) && (vpp >= 11400)) || ((vpp <= 3600) && (vpp >= 2700)))) begin VppErrFlag = `TRUE ; end if ((vpp <= 3600) && (vpp >= 2700)) begin if ((vcc >= 2700) && (vcc <= 3600)) begin Param_Erase_Time = `AC_EraseTime_Param_27_27; Main_Erase_Time = `AC_EraseTime_Main_27_27; Program_Time_Word = `AC_ProgramTime_Word_27_27; end else begin $display("FLASH: Invalid Vcc level at Vpp change"); VppErrFlag = `TRUE; end end else begin if ((vcc >= 2700) && (vcc <= 3600)) begin Param_Erase_Time = `AC_EraseTime_Param_27_12; Main_Erase_Time = `AC_EraseTime_Main_27_12; Program_Time_Word = `AC_ProgramTime_Word_27_12; end else begin $display("FLASH: Invalid Vcc level at Vpp change"); VppErrFlag = `TRUE; end end VppFlag <= VppErrFlag;endalways @(StartUpFlag or Internal_OE3) begin : OEMonitor // This section generated DriveOutputs which is the main signal that // controls the state of the output drivers if (!StartUpFlag) begin WriteRecovery = 0 ; last_Internal_WE_time = $time - curr_Internal_WE_time; if (Internal_OE) begin TempTime = WriteRecovery + TGLQX ; DriveOutputs = `FALSE ; WriteRecovery = WriteRecovery + TGLQV - TempTime; DriveOutputs <= #WriteRecovery `TRUE ; end else begin InternalOutput <= #TOH `MaxOutputs'hx; if (oeb == `VIH) WriteRecovery = WriteRecovery + TGHQZ; else WriteRecovery = WriteRecovery + TEHQZ; DriveOutputs <= #WriteRecovery `FALSE ; end end else DriveOutputs <= `FALSE ;end/////// Timing Checks /////////////always @(Internal_WE) begin : Timing_chk if ($time > 0) begin // pulse chk if (Internal_WE) begin if ((($time - curr_Internal_WE_time) < TWHWL) && (TWHWL > 0 )) begin $display("FLASH: [",$time,"] Timing Violation: Internal Write Enable Insufficient High Time") ; end end else if ((($time - curr_Internal_WE_time) < TWLWH) && (TWLWH > 0 )) $display("FLASH: [",$time,"] Timing Violation: Internal Write Enable Insufficient Low Time") ; curr_Internal_WE_time = $time ; // timing_chk - addr last_dq_time = $time - curr_dq_time; last_rpb_time = $time - curr_rpb_time; last_addr_time = $time - curr_addr_time; if (Internal_WE == 0) begin if ((last_addr_time < TAVWH) && (last_addr_time > 0)) $display("FLASH: [",$time,"] Timing Violation: Address setup time during write, Last Event %d",last_addr_time) ; if ((last_rpb_time < TPHWL) && (last_rpb_time > 0)) $display("FLASH: [",$time,"] Timing Violation: Writing while coming out of powerdown, Last Event %d",last_rpb_time) ; if ((last_dq_time < TDVWH) && (last_dq_time > 0)) $display("FLASH: [",$time,"] Timing Violation: Data setup time during write, Last Event %d",last_dq_time) ; end endend always @(addr) begin last_Internal_WE_time = $time - curr_Internal_WE_time; if (($time > 0) && !Internal_WE) begin //timing chk if ((last_Internal_WE_time < TWHAX) && (last_Internal_WE_time > 0)) $display("FLASH: [",$time,"] Timing Violation:Address hold time after write, Last Event %d",last_Internal_WE_time) ; endendalways @(rpb) begin if ((rpb_r != rpb) & ($time > 0)) begin curr_rpb_time = $time ; endendalways @(dq) begin curr_dq_time = $time ; last_Internal_WE_time = $time - curr_Internal_WE_time; if (($time > 0) && !Internal_WE) begin if ((last_Internal_WE_time < TWHDX) && (last_Internal_WE_time > 0)) $display("FLASH: [",$time,"] Timing Violation:Data hold time after write, Last Event %d",last_Internal_WE_time) ; endendendmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -