OpenCores
URL https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [verif/] [agents/] [spi/] [st_m25p20a/] [internal_logic.v] - Rev 17

Go to most recent revision | Compare with Previous | Blame | View Log

// Author: Mehdi SEBBANE
// May 2002
// Verilog model
// project: M25P20 25 MHz,
// release: 1.4.1
 
 
 
// These Verilog HDL models are provided "as is" without warranty
// of any kind, included but not limited to, implied warranty
// of merchantability and fitness for a particular purpose.
 
 
 
 
 
`ifdef SFLASH_SPDUP
`include "parameter_fast.v"
`else
`include "parameter.v"
`endif
 
module internal_logic (c, d, w, s, hold, data_to_read, q, data_to_write, page_add_index, add_mem, write_op, read_op, be_enable, se_enable, add_pp_enable, pp_enable, read_enable, data_request);
   ////////////////////////////////
   // declaration of the parameters
   ////////////////////////////////
   input c; 
   input d; 
   input w; 
   input s; 
   input hold; 
   input[(`NB_BIT_DATA - 1):0] data_to_read; 
 
   output q; 
   reg q;
 
   output[(`NB_BIT_DATA - 1):0] data_to_write;
   reg[(`NB_BIT_DATA - 1):0] data_to_write;
 
   output[(`LSB_TO_CODE_PAGE - 1):0] page_add_index;    // position to write data_to_write inside the page
   reg[(`LSB_TO_CODE_PAGE - 1):0] page_add_index;
 
   output[(`NB_BIT_ADD_MEM - 1):0] add_mem; 
   reg[(`NB_BIT_ADD_MEM - 1):0] add_mem;
 
   output write_op; 
   reg write_op;
 
   output read_op; 
   reg read_op;
 
   output be_enable; 
   reg be_enable;
 
   output se_enable; 
   reg se_enable;
 
   output add_pp_enable; 
   reg add_pp_enable;
 
   output pp_enable; 
   reg pp_enable;
 
   output read_enable; 
   reg read_enable;
 
   output data_request; 
   reg data_request;
 
 
   ///////////////////////////////////////////////
   // declaration of internal variables
   ///////////////////////////////////////////////
   reg only_rdsr;
   reg only_res;
   reg write_protect;
   reg select_ok;
   reg raz;
   reg byte_ok;
   reg wren;
   reg wrdi;
   reg rdsr;
   reg wrsr;
   reg read_data;
   reg fast_read;
   reg pp;
   reg se;
   reg be;
   reg dp;
   reg res;
   reg q_bis;
   reg protect;
   reg wr_cycle;
   reg hold_cond;
   reg inhib_wren;
   reg inhib_wrdi;
   reg inhib_rdsr;
   reg inhib_wrsr;
   reg inhib_read;
   reg inhib_pp;
   reg inhib_se;
   reg inhib_be;
   reg inhib_dp;
   reg inhib_res;
   reg reset_wel;
   reg wel;
   reg wip;
   reg c_int;
 
   reg [2:0]   cpt; 
   reg [2:0]   bit_index;       // to allow shift inside a byte 
   reg [2:0]   bit_res;         // to allow shift inside signature
   reg [2:0]   bit_register;    // to allow shift inside status register
 
   reg [7:0]   data; 
   reg [7:0]   adress_1; 
   reg [7:0]   adress_2; 
   reg [7:0]   adress_3; 
   reg [7:0]   sr_mask; 
   reg [7:0]   signature; 
 
   reg [(`NB_BIT_DATA-1):0]   wr_latch; 
   reg [(`NB_BIT_DATA-1):0]   page_ini; 
   reg [(`NB_BIT_DATA-1):0]   data_latch;
   reg [(`NB_BIT_DATA-1):0]   register_bis; 
   reg [(`NB_BIT_DATA-1):0]   register_temp;
   reg [(`NB_BIT_DATA-1):0]   status_register;
 
   reg [(`NB_BPI-1):0]              bp; 
   reg [(`NB_BIT_ADD_MEM-1):0]      adress; 
   reg [(`BIT_TO_CODE_MEM-1):0]     cut_add; 
   reg [(`LSB_TO_CODE_PAGE -1) :0]  lsb_adress; 
 
   integer     byte_cpt;
   integer     int_add; 
   integer     i;
   integer     count_enable; 
 
   time        t_only_res ;
 
   initial
   begin
      ////////////////////////////////////////////
      // Initialization of the internal variables
      ////////////////////////////////////////////
      only_rdsr      = `FALSE;
      only_res       = `FALSE;
      write_protect  = `FALSE;
      select_ok      = `FALSE;
      raz            = `FALSE;
      byte_ok        = `FALSE;
 
      cpt         = 0;
      byte_cpt    = 0;
 
      data_to_write  = 8'bxxxxxxxx;
      data_latch     = 8'bxxxxxxxx;
      data_request <= `FALSE;
 
      wren        = `FALSE;
      wrdi        = `FALSE;
      rdsr        = `FALSE;
      wrsr        = `FALSE;
      read_data   = `FALSE;
      fast_read   = `FALSE;
      pp          = `FALSE;
      se          = `FALSE;
      be          = `FALSE;
      dp          = `FALSE;
      res         = `FALSE;
 
      q_bis          = 1'bz;
 
      register_bis   = 8'b00000000;
      wr_latch       = 8'b00000000;
 
      protect     = `FALSE;
      wr_cycle    = `FALSE;
      hold_cond   = `FALSE;
      write_op    = `FALSE;
      read_op     = `FALSE;
 
      inhib_wren  = `FALSE;
      inhib_wrdi  = `FALSE;
      inhib_rdsr  = `FALSE;
      inhib_wrsr  = `FALSE;
      inhib_read  = `FALSE;
      inhib_pp    = `FALSE;
      inhib_se    = `FALSE;
      inhib_be    = `FALSE;
      inhib_dp    = `FALSE;
      inhib_res   = `FALSE;
 
      add_pp_enable  = `FALSE;
      read_enable    = `FALSE;
      pp_enable      = `FALSE;
      be_enable      = `FALSE;
      se_enable      = `FALSE;
 
 
      count_enable   = `FALSE;
      data           = 8'b00000000;
 
      // decode process
      bit_index      = 8'b00000000;
      bit_res        = 8'b00000000;
      bit_register   = 8'b00000000;
 
      bp          = `NB_BPI'h0 ;
 
      int_add     = 0;
      sr_mask     = 8'b10000000;
      page_ini    = 8'b11111111;
 
      reset_wel   = 1'b0;
      wel         = 1'b0;
      wip         = 1'b0;
 
      signature   = `SIGNATURE ;
   end // initial
 
   always @(register_bis) status_register = register_bis ;
   //assign status_register = register_bis ; // Continuous Assignment
 
   //-----------------------------------------------------------
   // This process generates the Hold condition when it is valid
   always 
   begin : hold_com
      @(hold); 
      begin
      if ((hold == 1'b0) && (s == 1'b0))
      begin
         if (c == 1'b0)
         begin
            hold_cond <= `TRUE;
            if ($time != 0) $display("NOTE: COMMUNICATION PAUSED"); 
         end
         else
         begin
            @(c or hold); 
            if (c == 1'b0)
            begin
               hold_cond <= `TRUE;
               if ($time != 0) $display("NOTE: COMMUNICATION PAUSED"); 
            end 
         end 
      end
      else if (hold == 1'b1)
      begin
         if (c == 1'b0)
         begin
            hold_cond <= `FALSE;
            if ($time != 0) $display("NOTE: COMMUNICATION (RE)STARTED"); 
         end
         else
         begin
            @(c or hold); 
            if (c == 1'b0)
            begin
               hold_cond <= `FALSE;
               if ($time != 0) $display("NOTE: COMMUNICATION (RE)STARTED"); 
            end 
         end 
      end
      end
   end 
 
   //----------------------------------------------------------------------
   // This process inhibits the internal clock when hold condition is valid
   always 
   begin : horloge
      @(c); 
      begin
      if (!hold_cond)
      begin
         c_int <= c ; 
      end
      else
      begin
         c_int <= 1'b0 ; 
      end 
      end
   end 
 
   //---------------------------------------------------------------
   // This process inhibits data output when hold condition is valid
   always @(posedge hold_cond ) q <= #`THLQZ 1'bz ;
 
   always @(negedge hold_cond) q <= #`THHQX q_bis ; 
 
   always @ (q_bis or s)
      if (!hold_cond)
      begin
         q <= q_bis ; 
      end
 
   //----------------------------------------------------------
   // This process increments 2 counters:  one bit counter (cpt)
   // one byte counter (byte_cpt)
   always 
   begin : count_bit_raz
         @(raz); 
         begin
            if (raz || !select_ok)
            begin
               cpt <= 0 ; 
               byte_cpt <= 0 ; 
               count_enable = `FALSE; 
            end
         end
   end 
 
   always 
   begin : count_bit_enable
      @(posedge c_int or negedge raz);
      begin
            if (!raz && select_ok)
            begin
               // count enable is an intermediate variable which allows cpt to be
               // constant during a whole period
               count_enable = `TRUE; 
            end
      end
   end
 
 
   always 
   begin : count_bit
      @(negedge c_int);
      begin
         if (!raz && select_ok)
         begin
            if (count_enable)
            begin
               cpt <= cpt + 1 ; 
            end 
         end 
      end
   end 
 
   always @(negedge c_int)
      if (byte_ok)
      begin
         //byte_cpt = (byte_cpt + 1) ; 
         byte_cpt <= (byte_cpt + 1) ; 
      end 
 
   //---------------------------------------------------------------------
   // This process latches every byte of data received and returns byte_ok 
   always 
   begin : data_in_reset
 
      @(c_int or select_ok); 
      begin
         if (!select_ok)
         begin
            raz <= `TRUE ; 
            byte_ok <= `FALSE ; 
            data_latch <= 8'b00000000 ; 
            data = 8'b00000000;
         end
      end
   end
 
   always 
   begin : data_in
 
      @(posedge c_int); 
      begin
      if (select_ok)
      begin
         raz <= `FALSE ; 
         if (cpt == 0)
         begin
            data_latch <= 8'b00000000 ; 
            byte_ok <= `FALSE ; 
         end 
         data[7 - cpt] = d; 
         if (cpt == 7)
         begin
            byte_ok <= `TRUE ; 
            data_latch <= data ; 
         end 
         else data_latch <= 8'bxxxxxxxx;
      end 
      end
   end 
 
   //-------------------------------------------------------------
   //--------------- ASYNCHRONOUS DECODE PROCESS -----------------
   //-------------------------------------------------------------
   always 
   begin : decode
      //-------------------------
      // status register mask ini
      //-------------------------
      for(i = 0; i <= (`NB_BPI - 1); i = i + 1)
      begin
         sr_mask[i + 2] = 1'b1; 
      end
 
 
      @(byte_ok); 
      if (byte_ok == 1'b1)
      begin         
         //-----------------------------------------------------------
         //-- op_code decode
         //-----------------------------------------------------------
         if (byte_cpt == 0)
         begin
            if (data_latch == 8'b00000110)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle"); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR :This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  wren <= `TRUE ; 
                  write_op <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b00000100)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  wrdi <= `TRUE ; 
                  write_op <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b00000101)
            begin
               if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  rdsr <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b00000001)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  wrsr <= `TRUE ; 
                  write_op <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b00000011)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  read_data <= `TRUE ; 
                  read_op <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b00001011)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  fast_read <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b00000010)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  pp <= `TRUE ; 
                  write_op <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b11011000)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  se <= `TRUE ; 
                  write_op <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b11000111)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  be <= `TRUE ; 
                  write_op <= `TRUE ; 
                  for(i = 0; i <= (`NB_BPI - 1); i = i + 1)
                  begin
                     bp[i] = status_register[i + 2]; 
                  end
                  if (bp != 2'b00)
                  begin
                     protect <= `TRUE ; 
                     write_op <= `FALSE ; 
                  end 
               end 
            end
            else if (data_latch == 8'b10111001)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else if (only_res)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a DEEP POWER DOWN "); 
               end
               else
               begin
                  dp <= `TRUE ; 
               end 
            end
            else if (data_latch == 8'b10101011)
            begin
               if (only_rdsr)
               begin
                  if ($time != 0) $display("ERROR : This Opcode is not decoded during a Prog. Cycle "); 
               end
               else
               begin
                  res <= `TRUE ; 
               end 
            end
            else
            begin
               if ($time != 0) $display("ERROR : False instruction, please retry "); 
            end 
         end
         //---------------------------------------------------------------------
         // addresses and data reception and treatment
         //---------------------------------------------------------------------
         if ( (byte_cpt == 1) && (!only_rdsr) && (!only_res))
         begin
            if (((read_data) || (fast_read) || (se) || (pp)) && (!rdsr))
            begin
               adress_1 = data_latch; 
            end
            else if (wrsr && (!rdsr))
            begin
               wr_latch <= data_latch ; 
            end 
         end 
 
         if ((byte_cpt == 2) && (!only_rdsr) && (!only_res))
         begin
            if (((read_data) || (fast_read) || (se) || (pp)) && (!rdsr))
            begin
               adress_2 = data_latch; 
            end 
         end 
         if ((byte_cpt == 3) && (!only_rdsr) && (!only_res))
         begin
            if (((read_data) || (fast_read) || (se) || (pp)) && (!rdsr))
            begin
               adress_3 = data_latch; 
               for(i = 0; i <= (`NB_BIT_ADD - 1); i = i + 1)
               begin
                  adress[i] = adress_3[i]; 
                  adress[i + `NB_BIT_ADD] = adress_2[i]; 
                  adress[i + 2 * `NB_BIT_ADD] = adress_1[i]; 
                  add_mem <= adress ; 
               end
               for(i = (`LSB_TO_CODE_PAGE - 1); i >= 0; i = i - 1)
               begin
                  lsb_adress[i] = adress[i]; 
               end
            end 
            if ((se || pp) && (!rdsr))
            begin
               //-----------------------------------------
               // To ignore don't care MSB of the adress
               //----------------------------------------- 
               for(i = 0; i <= `BIT_TO_CODE_MEM -1; i = i + 1)
               begin
                  cut_add[i] = adress[i]; 
               end
               int_add = cut_add; 
               //------------------------------------------------
               // Sector protection detection
               //------------------------------------------------
               for(i = 0; i <= (`NB_BPI - 1); i = i + 1)
               begin
                  bp[i] = status_register[i + 2]; 
               end
               if (bp == 2'b11)
               begin
                  protect <= `TRUE ; 
                  write_op <= `FALSE ; 
               end
               else if (bp == 2'b10)
               begin
                  if (int_add >= ((`TOP_MEM + 1) / 2))
                  begin
                     protect <= `TRUE ; 
                     write_op <= `FALSE ; 
                  end 
               end
               else if (bp == 2'b01)
               begin
                  if (int_add >= ((`TOP_MEM + 1) * 3 / 4))
                  begin
                     protect <= `TRUE ; 
                     write_op <= `FALSE ; 
                  end 
               end
               else
               begin
                  protect <= `FALSE ; 
               end 
            end 
         end 
         //---------------------------------------------------------------------------
         // PAGE PROGRAM
         // The adress's LSBs necessary to code a whole page are converted to a natural
         // and used to fullfill the page buffer p_prog the same way as the memory page
         // will be fullfilled.
         //--------------------------------------------------------------------------
         if ( (byte_cpt >= 4) && (pp) && (!only_rdsr) && (!rdsr))
         begin
            data_to_write = data_latch ; 
            page_add_index = (byte_cpt - 1 - (`NB_BIT_ADD_MEM / `NB_BIT_ADD) + lsb_adress); 
         end 
         else
         begin
            data_to_write  = 8'bxxxxxxxx; 
            page_add_index = 8'bxxxxxxxx; 
         end
 
         // to launch adress treatment in memory access
         if (( read_data && (byte_cpt == 3)) || (fast_read && (byte_cpt == 4)))
         begin
            read_enable <= `TRUE ; 
         end 
         // to send a request for the data pointed by the adress
         if (( read_data && (byte_cpt >= 3)) || ( fast_read && (byte_cpt >= 4)))
         begin
            data_request <= `TRUE ; 
         end 
      end   //(if byte_ok)
   end   //(process decode)
 
   //-----------------------------------------
   // adresses initialization and reset
   //-----------------------------------------
   always @(posedge select_ok) 
   begin
      for(i = 0; i <= (`NB_BIT_ADD - 1); i = i + 1)
      begin
         adress_1[i] = 1'b0; 
         adress_2[i] = 1'b0; 
         adress_3[i] = 1'b0; 
      end
      for(i = 0; i <= (`NB_BIT_ADD_MEM - 1); i = i + 1)
      begin
         adress[i] = 1'b0; 
      end
      add_mem <= adress ; 
   end
 
 
   always @(negedge byte_ok)
   begin
      if ((read_data && (byte_cpt > 3) ) || (fast_read && (byte_cpt > 4) ))
      begin
         data_request <= `FALSE ; 
 
      end 
   end
 
   always @(posedge inhib_read)
   begin
         read_op <= `FALSE ; 
         read_data <= `FALSE ; 
         fast_read <= `FALSE ; 
         read_enable <= `FALSE ; 
         data_request <= `FALSE ; 
 
   end
   //------------------------------------------------------
   // STATUS REGISTER INSTRUCTIONS
   //------------------------------------------------------
   // WREN/WRDI instructions
   //-----------------------
   always @(posedge wel)
   begin
      register_bis[1] <= 1'b1 ; 
 
   end
 
   always @(posedge inhib_wren) 
   begin
      wren <= `FALSE ; 
      write_op <= `FALSE ; 
   end 
 
   always @(posedge inhib_wrdi)
   begin
      wrdi <= `FALSE ; 
      write_op <= `FALSE ; 
   end 
 
   //----------------------
   // RESET WEL instruction
   //----------------------
   always @(posedge reset_wel)
   begin
      register_bis[1] <= 1'b0 ; 
   end 
   //-------------------
   // WRSR instructions
   //-------------------
   always @(posedge wr_cycle)
      begin
         if ($time != 0) $display("NOTE : Write status register cycle has begun "); 
         register_bis <= ((register_bis) | (8'b00000011)) ; 
      end 
   always @(negedge wr_cycle)
      begin
         if ($time != 0) $display("NOTE : Write status register cycle is finished"); 
         register_bis <= ((wr_latch) & sr_mask) ; 
         wrsr <= `FALSE ; 
      end 
 
   always @(posedge inhib_wrsr) wrsr <= `FALSE ; 
 
   always @(negedge wrsr) wr_latch <= 8'b00000000 ; 
 
   //------
   // PROG
   //------
   always @(wip)
   begin
      if (wip == 1'b1)
      begin
         register_bis[0] <= 1'b1 ; 
      end 
      else
      begin
         register_bis[0] <= 1'b0 ; 
         write_op <= `FALSE ; 
 
      end 
   end
   //------------------
   // rdsr instruction
   //------------------
   always @(posedge inhib_rdsr) rdsr <= `FALSE ; 
   //----------------------------------------------------------
   // BULK/SECTOR ERASE INSTRUCTIONS
   //----------------------------------------------------------
   always @(posedge inhib_be)
   begin
      protect <= `FALSE ; 
      be <= `FALSE ; 
   end 
   always @(posedge inhib_se)
   begin
      protect <= `FALSE ; 
      se <= `FALSE ; 
   end 
   //----------------------------------------------------------
   //PAGE PROGRAM INSTRUCTIONS
   //----------------------------------------------------------
   always @(posedge inhib_pp)
   begin
      protect <= `FALSE ; 
      pp <= `FALSE ; 
   end 
   //----------------------------------------------------------
   // DEEP POWER DOWN
   // RELEASE FROM DEEP POWER DOWN AND READ ELECTRONIC SIGNATURE
   //-----------------------------------------------------------
   always @(posedge inhib_dp) dp <= `FALSE ; 
 
   always @(posedge inhib_res) res <= `FALSE ; 
 
   //--------------------------------------------------------
   //--------------- SYNCHRONOUS PROCESS  ----------------
   //--------------------------------------------------------
   always 
   @(c_int or select_ok)
   begin
      wel <= 1'b0 ; 
      reset_wel <= 1'b0 ; 
   end
 
      //-------------------------------------------
      // READ_data
      //-------------------------------------------
   always 
      @(c_int or select_ok)
      begin
         if ((!read_data) && (!fast_read))
         begin
            inhib_read <= `FALSE ; 
         end 
         if (((byte_cpt == 0) || (byte_cpt == 1) || (byte_cpt == 2) || ((byte_cpt == 3) && (cpt != 7))) && read_data && (!select_ok))
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is deselected"); 
            inhib_read <= `TRUE ; 
            bit_index <= 8'b00000000; 
         end 
         if (read_data && (((byte_cpt == 3) && (cpt == 7)) || (byte_cpt >= 4)))
         begin
            if (!select_ok)
            begin
               inhib_read <= `TRUE ; 
               bit_index <= 8'b00000000; 
               q_bis <= #`TSHQZ 1'bz ; 
            end
         end
      end
 
   always 
   @(negedge c_int)
   begin
      if (read_data && (((byte_cpt == 3) && (cpt == 7)) || (byte_cpt >= 4)))
      begin
 
         if (select_ok)
         begin
            q_bis <= #`TCLQV data_to_read[7 - bit_index] ; 
            bit_index = bit_index + 1; 
         end 
      end
   end
 
      //------------------------------------------------------------------
      // Fast_Read
      //------------------------------------------------------------------
   always 
      @(c_int or select_ok)
      begin
         if (((byte_cpt == 0) || (byte_cpt == 1) || (byte_cpt == 2) || (byte_cpt == 3) || ((byte_cpt == 4) && (cpt != 7))) && fast_read && (!select_ok))
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is deselected"); 
            inhib_read <= `TRUE ; 
            bit_index <= 8'b00000000; 
         end 
         if (fast_read && (((byte_cpt == 4) && (cpt == 7)) || (byte_cpt >= 5)))
         begin
            if (!select_ok)
            begin
               inhib_read <= `TRUE ; 
               bit_index <= 8'b00000000; 
               q_bis <= #`TSHQZ 1'bz ; 
            end
         end
      end
 
   always 
      @(negedge c_int)
      begin
         if (fast_read && (((byte_cpt == 4) && (cpt == 7)) || (byte_cpt >= 5)))
         begin
            if (select_ok)
            begin
               q_bis <= #`TCLQV data_to_read[7 - bit_index] ; 
               bit_index = bit_index + 1 ;
            end 
         end
      end
 
      //-----------------------------------------
      // Write_enable 
      //-----------------------------------------
   always 
      @(c_int or select_ok)
      begin
         if (!wren)
         begin
            inhib_wren <= `FALSE ; 
         end
         if (wren && (!only_rdsr) && (!only_res))
         begin
            if (!select_ok)
            begin
               wel <= 1'b1 ; 
               inhib_wren <= `TRUE ; 
            end
         end
      end
 
   always 
      @(posedge c_int)
      begin
         if (wren && (!only_rdsr) && (!only_res) && select_ok)
         begin
            inhib_wren <= `TRUE ; 
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is still selected"); 
         end
      end
 
      //-------------------------------------------
      // Write_disable
      //-------------------------------------------
   always 
      @(c_int or select_ok)
      begin
         if (!wrdi)
         begin
            inhib_wrdi <= `FALSE ; 
         end 
         if (wrdi && (!only_rdsr) && (!only_res))
         begin
            if (!select_ok)
            begin
               reset_wel <= 1'b1 ; 
               inhib_wrdi <= `TRUE ; 
            end 
         end
      end
 
   always 
      @(posedge c_int)
      begin
         if (wrdi && (!only_rdsr) && (!only_res) && select_ok)
         begin
            inhib_wrdi <= `TRUE ; 
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is still selected"); 
         end
      end
 
      //-----------------------------------------
      // Write_status_register
      //-----------------------------------------
   always 
      @(c_int or select_ok)
      begin
         if (!wrsr)
         begin
            inhib_wrsr <= `FALSE ; 
         end 
         if (wrsr && (!only_rdsr) && (!only_res))
         begin
            if ((byte_cpt == 1) && ((cpt != 7) || (!byte_ok)) && (!wr_cycle))
            begin
               if (!select_ok)
               begin
                  if ($time != 0) $display("WARNING : Instruction canceled because the chip is deselected"); 
                  inhib_wrsr <= `TRUE ; 
               end 
            end
            else if ((byte_cpt == 1) && (cpt == 7) && byte_ok)
            begin
               if (write_protect)
               begin
                  if ($time != 0) $display("WARNING : Instruction canceled because status register is hardware protected"); 
                  inhib_wrsr <= `TRUE ; 
               end
            end
         end
      end
 
   always 
      @(negedge select_ok)
      begin
         if (wrsr && (!only_rdsr) && (!only_res))
         begin
            if ((byte_cpt == 1) && (cpt == 7) && byte_ok && (!write_protect))
            begin
               if ((status_register[1]) == 1'b0)
               begin
                  if ($time != 0) $display("WARNING : Instruction canceled because WEL is reset"); 
                  inhib_wrsr <= `TRUE ; 
               end
               else
               begin
                  wr_cycle <= `TRUE ; 
                  wip <= 1'b1 ; 
                  #`TW; 
                  wip <= 1'b0 ; 
                  wr_cycle <= `FALSE ; 
               end 
            end
            else if (byte_cpt == 2)
            begin
               if ((status_register[1]) == 1'b0)
               begin
                  if ($time != 0) $display("WARNING : Instruction canceled because WEL is reset"); 
                  inhib_wrsr <= `TRUE ; 
               end
               else
               begin
                  wr_cycle <= `TRUE ; 
                  wip <= 1'b1 ; 
                  #`TW; 
                  wr_cycle <= `FALSE ; 
                  wip <= 1'b0 ; 
               end 
            end
         end
      end
 
   always @(posedge c_int)
   begin
      if (wrsr && (!only_rdsr) && (!only_res))
         if (byte_cpt == 2 && !rdsr)
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is still selected"); 
            inhib_wrsr <= `TRUE ; 
         end
      end
 
      //-------------------------------------------
      // Bulk_erase
      //-------------------------------------------
   always @( c_int or select_ok)
   begin
      if (!be)
      begin
         inhib_be <= `FALSE ; 
      end 
      if (be && (!only_rdsr) && (!only_res))
      begin
         if (!select_ok)
         begin
            if ((status_register[1]) == 1'b0)
            begin
               if ($time != 0) $display("WARNING : Instruction canceled because WEL is reset"); 
               be_enable <= `FALSE ; 
               inhib_be <= `TRUE ; 
            end
            else if (protect && be)
            begin
               if ($time != 0) $display("WARNING : Instruction canceled because at least one sector is protected"); 
               be_enable <= `FALSE ; 
               inhib_be <= `TRUE ; 
            end
            else
            begin
               if ($time != 0) $display("NOTE : Bulk erase cycle has begun"); 
               be_enable <= `TRUE ; 
               wip <= 1'b1 ; 
               // We can't use `TBE since it wider than a 32bits number
               // and the delay instruction can only manage 32bits wide number
               #`TSE ;
               #`TSE ;
               if ($time != 0) $display("NOTE : Bulk erase cycle is finished"); 
               be_enable <= `FALSE ; 
               inhib_be <= `TRUE ; 
               wip <= 1'b0 ; 
               reset_wel <= 1'b1 ; 
            end
         end
      end
   end
 
   always @(posedge c_int)
   begin
      if (be && (!only_rdsr) && (!only_res))
      begin
         if ($time != 0) $display("WARNING : Instruction canceled because the chip is still selected"); 
         inhib_be <= `TRUE ; 
      end
   end
 
      //-------------------------------------------
      // Sector_erase
      //-------------------------------------------
   always @( c_int or select_ok)
   begin
      if (!se)
      begin
         inhib_se <= `FALSE ; 
      end 
      if (((byte_cpt == 0) || (byte_cpt == 1) || (byte_cpt == 2) || ((byte_cpt == 3) && ((cpt != 7) || !byte_ok))) && se && (!only_rdsr) && (!only_res))
      begin
         if (!select_ok)
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is deselected"); 
            inhib_se <= `TRUE ; 
         end 
      end 
      if ( ((byte_cpt == 4) || ((byte_cpt == 3) && (cpt == 7) && byte_ok)) && se && (!only_rdsr) && (!only_res))
      begin
         if (!select_ok)
         begin
            if ((status_register[1]) == 1'b0)
            begin
               if ($time != 0) $display("WARNING : Instruction canceled because WEL is reset"); 
               se_enable <= `FALSE ; 
               inhib_se <= `TRUE ; 
            end
            else if (protect && se)
            begin
               if ($time != 0) $display("WARNING : Instruction canceled because the SE sector is protected"); 
               se_enable <= `FALSE ; 
               inhib_se <= `TRUE ; 
            end
            else
            begin
               if ($time != 0) $display("NOTE : Sector erase cycle has begun"); 
               se_enable <= `TRUE ; 
               wip <= 1'b1 ; 
               #`TSE ;
               if ($time != 0) $display("NOTE : Sector erase cycle is finished"); 
               se_enable <= `FALSE ; 
               inhib_se <= `TRUE ; 
               wip <= 1'b0 ; 
               reset_wel <= 1'b1 ; 
            end 
         end 
      end
   end
 
   always @(posedge c_int)
   begin
      if ( ((byte_cpt == 4) || ((byte_cpt == 3) && (cpt == 7) && byte_ok)) && se && (!only_rdsr) && (!only_res))
      begin
         if (byte_cpt == 4 && select_ok)
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is still selected"); 
            inhib_se <= `TRUE ; 
         end
      end
   end
 
      //-------------------------------------------
      // Page_Program
      //-------------------------------------------
   always @(c_int or select_ok)
   begin
      if (!pp)
      begin
         inhib_pp <= `FALSE ; 
         add_pp_enable <= `FALSE ; 
         pp_enable <= `FALSE ; 
      end 
 
      if (((byte_cpt == 5) || ((byte_cpt == 4) && (cpt == 7))) && pp && (!only_rdsr) && (!only_res))
      begin
         add_pp_enable <= `TRUE ; 
         if ((status_register[1]) == 1'b0)
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because WEL is reset"); 
            pp_enable <= `FALSE ; 
            inhib_pp <= `TRUE ; 
         end
         else if (protect && pp)
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the PP sector is protected"); 
            pp_enable <= `FALSE ; 
            inhib_pp <= `TRUE ; 
         end 
      end 
   end
 
   always @(negedge select_ok)
   begin
      if (((byte_cpt == 0) || (byte_cpt == 1) || (byte_cpt == 2) || (byte_cpt == 3) || ((byte_cpt == 4) && ((cpt != 7) || !byte_ok))) && pp && (!only_rdsr) && (!only_res) && (!select_ok))
         begin
            if ($time != 0) $display("WARNING : Instruction canceled because the chip is deselected"); 
            inhib_pp <= `TRUE ; 
         end 
      if (((byte_cpt == 5) || ((byte_cpt == 4) && (cpt == 7))) && pp && (!only_rdsr) && (!only_res))
      begin
         add_pp_enable <= `TRUE ; 
         if (pp)
         begin
            if ($time != 0) $display("NOTE : Page program cycle is started"); 
            wip <= 1'b1 ; 
            #`TPP; 
            if ($time != 0) $display("NOTE : Page program cycle is finished"); 
            pp_enable <= `TRUE ; 
            wip <= 1'b0 ; 
            inhib_pp <= `TRUE ; 
            reset_wel <= 1'b1 ; 
         end 
      end 
      if ((byte_cpt > 5) && pp && (!only_rdsr) && (!only_res) && byte_ok)
      begin
         if ($time != 0) $display("NOTE : Page program cycle is started"); 
         wip <= 1'b1 ; 
         #`TPP; 
         if ($time != 0) $display("NOTE : Page program cycle is finished"); 
         pp_enable <= `TRUE ; 
         wip <= 1'b0 ; 
         inhib_pp <= `TRUE ; 
         reset_wel <= 1'b1 ; 
      end 
      if ((byte_cpt > 5) && pp && (!only_rdsr) && (!only_res) && (!byte_ok))
      begin
         if ($time != 0) $display("WARNING : Instruction canceled because the chip is deselected"); 
         inhib_pp <= `TRUE ; 
         pp_enable <= `FALSE ; 
      end 
   end
 
      //-----------------------------------------
      // Deep Power Down
      //-----------------------------------------
   always @(c_int or select_ok)
   begin
      if (!dp)
      begin
         inhib_dp <= `FALSE ; 
         only_res <= `FALSE ; 
         t_only_res = 0;
      end 
   end
 
   always @(posedge c_int)
   begin
      if (dp && (!only_rdsr) && (!only_res) && (!res))
      begin
         if ($time != 0) $display("WARNING : Instruction canceled because the chip is still selected"); 
         inhib_dp <= `TRUE ; 
         only_res <= `FALSE ; 
         t_only_res = 0;
      end
   end
 
   always @(negedge select_ok)
   begin
      if (dp && (!only_rdsr) && (!only_res) && (!res))
      begin
         if ($time != 0) $display("NOTE : Chip is entering deep power down mode"); 
         // useful when chip is selected again to inhib every op_code except RES
         // and to check tDP
         t_only_res = $time;
         only_res <= `TRUE ; 
 
      end
   end
 
      //---------------------------------------------------------------------
      // Release from Deep Power Down Mode and Read Electronic Signature
      //---------------------------------------------------------------------
   always @(select_ok or c_int)
   begin
      if (!res)
      begin
         inhib_res <= `FALSE ; 
         bit_res <= 0; 
      end 
 
      if (res && ((byte_cpt == 1) && (cpt == 0)) && (!only_rdsr) && (!select_ok))
      begin
      if (only_res)
      begin
         if ($time != 0) $display("NOTE : The chip is releasing from DEEP POWER DOWN"); 
      end
         inhib_res <= `FALSE; 
         inhib_dp <= `FALSE; 
         #`TRES1;
         inhib_res <= `TRUE; 
         inhib_dp <= `TRUE; 
      end
      else if ((((byte_cpt == 1) && (cpt > 0)) || (byte_cpt == 2) || (byte_cpt == 3) || ((byte_cpt == 4) && ((cpt < 7) || (!byte_ok)))) && res && (!only_rdsr) && (!select_ok))
      begin
         if ($time != 0) $display("ERROR : Electronic Signature must be read at least once. Instruction not valid"); 
      end
      else if ((((byte_cpt == 4) && (cpt == 7) && byte_ok) || (byte_cpt > 4)) && res && (!only_rdsr) && (!select_ok))
      begin
         #`TRES2;
         inhib_res <= `TRUE ; 
         inhib_dp <=  `TRUE ; 
         if (only_res)
         begin
            if ($time != 0) $display("NOTE : The Chip is releasing from DEEP POWER DOWN"); 
         end
         q_bis <= 1'bz ; 
      end
   end
 
   always @(negedge c_int)
   begin
      if ((((byte_cpt == 3) && (cpt == 7)) || (byte_cpt >= 4)) && res && (!only_rdsr) )
      begin
         q_bis <= #`TCLQV signature[7 - bit_res] ; 
         bit_res = bit_res + 1; 
      end 
   end
 
   //-------------------------------------------------------
   // This process shifts out status register on data output
   always 
      @(c_int or select_ok or rdsr)
      begin
         if (!rdsr)
         begin
            inhib_rdsr <= `FALSE ; 
         end 
         if (rdsr && (!select_ok))
         begin
            bit_register <= 0; 
            q_bis <= #`TSHQZ 1'bz ; 
            inhib_rdsr <= `TRUE ; 
         end
      end
 
   always 
      @(negedge c_int)
      begin
         if (rdsr && (select_ok))
         begin
            q_bis <= #`TCLQV status_register[7 - bit_register] ; 
            bit_register = bit_register + 1; 
         end
      end
   //--------------------------------------------------------------------------------------
   // This process checks select and deselect conditions. Some other conditions are tested:
   // prog cycle, deep power down mode and read electronic signature.
   always 
   begin : pin_s
      @(s); 
      begin
      if (s == 1'b0)
      begin
         if (res && only_res)
         begin
            if ($time != 0) $display("ERROR : The chip must not be selected until tRES"); 
         end
         else if (dp)
         begin
            if (($time - t_only_res) < `TDP)
            begin
               if ($time != 0) $display("ERROR : The chip must not be selected until tDP"); 
            end
            else
            begin
               if ($time != 0) $display("NOTE : Only a Read Electronic Signature instruction will be valid"); 
            end 
         end 
         select_ok <= `TRUE ; 
         if (pp || wrsr || be || se)
         begin
            if ($time != 0) $display("NOTE : Only a Read Status Register instruction will be valid"); 
            only_rdsr <= `TRUE ; 
         end 
      end 
      else
      begin
         select_ok <= `FALSE ; 
         only_rdsr <= `FALSE ; 
      end 
      end
   end 
 
   //--------------------------------------------------------------
   // This Process detects the hardware protection mode
   always 
      @(w or c_int)
      begin
         if ((w == 1'b0) && ((status_register[7]) == 1'b1))
         begin
            write_protect <= `TRUE ; 
         end 
         if (w == 1'b1)
         begin
            write_protect <= `FALSE ; 
         end 
      end 
endmodule
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.