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