⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 adv_bb.v

📁 memory control source code
💻 V
📖 第 1 页 / 共 3 页
字号:
         endcase 
       end  //default
    endcase
  end  //if
end  //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 
  end
end  //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 ;
  end
end

// record the time for oe changes .
always @(oeb) begin
  if ($time != 0) begin
    curr_oe_time = $time ;
  end
end

// record the time for ce changes .
always @(ceb) begin
  if ($time != 0) begin
    curr_ce_time = $time ;
  end
end

reg 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;
  end
end

// record the time for ReadMode changes .
always @(ReadMode) begin
  if ($time != 0) begin
    curr_ReadMode_time = $time ;
  end
end

// record the time for Internal_RE changes .
always @(Internal_RE) begin
  if ($time != 0) begin
    curr_Internal_RE_time = $time ;
  end
end

always @(InternalBoot) begin
  InternalBoot_WE <= #TVPWH InternalBoot;
end

always @(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 //$time
end

//------------------------------------------------------------------------
// 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;
end


always @(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 
  end
end  

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) ;
  end
end

always @(rpb) begin
  if ((rpb_r != rpb) & ($time > 0)) begin
    curr_rpb_time = $time ;
  end
end

always @(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) ;
  end
end

endmodule


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -