////////////////////////////////////////////////////////////////////////////// // File name : s29as016j.v ////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2007 Free Model Foundry; http://www.FreeModelFoundry.com // // This program is free software; you can redistribute it and/or modify // it under the terms of the GNU General Public License version 2 as // published by the Free Software Foundation. // // MODIFICATION HISTORY : // // version: | author: | mod date: | changes made: // V1.0 D.Popovic 07 April 25 Initial release // ////////////////////////////////////////////////////////////////////////////// // PART DESCRIPTION: // // Library: FLASH // Technology: Flash Memory // Part: S29AS016J // // Description: 16 Megabit (2 M x 8-Bit/1 M x 16-Bit) CMOS 1.8 Volt-only // Boot Sector Flash Memory // ////////////////////////////////////////////////////////////////////////////// // Known Bugs: // ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // MODULE DECLARATION // ////////////////////////////////////////////////////////////////////////////// `timescale 1 ns/1 ns module s29as016j ( A19, A18, A17, A16, A15, A14, A13, A12, A11, A10, A9, A8, A7, A6, A5, A4, A3, A2, A1, A0, DQ15, DQ14, DQ13, DQ12, DQ11, DQ10, DQ9, DQ8, DQ7, DQ6, DQ5, DQ4, DQ3, DQ2, DQ1, DQ0, CENeg, OENeg, WENeg, WPNeg, RESETNeg, BYTENeg, RY); //////////////////////////////////////////////////////////////////////// // Port / Part Pin Declarations //////////////////////////////////////////////////////////////////////// input A19; input A18; input A17; input A16; input A15; input A14; input A13; input A12; input A11; input A10; input A9; input A8; input A7; input A6; input A5; input A4; input A3; input A2; input A1; input A0; inout DQ15; inout DQ14; inout DQ13; inout DQ12; inout DQ11; inout DQ10; inout DQ9; inout DQ8; inout DQ7; inout DQ6; inout DQ5; inout DQ4; inout DQ3; inout DQ2; inout DQ1; inout DQ0; input CENeg; input OENeg; input WENeg; input WPNeg; input BYTENeg; input RESETNeg; output RY; // interconnect path delay signals wire A19_ipd; wire A18_ipd; wire A17_ipd; wire A16_ipd; wire A15_ipd; wire A14_ipd; wire A13_ipd; wire A12_ipd; wire A11_ipd; wire A10_ipd; wire A9_ipd; wire A8_ipd; wire A7_ipd; wire A6_ipd; wire A5_ipd; wire A4_ipd; wire A3_ipd; wire A2_ipd; wire A1_ipd; wire A0_ipd; wire [19 : 0] A; assign A = { A19_ipd, A18_ipd, A17_ipd, A16_ipd, A15_ipd, A14_ipd, A13_ipd, A12_ipd, A11_ipd, A10_ipd, A9_ipd, A8_ipd, A7_ipd, A6_ipd, A5_ipd, A4_ipd, A3_ipd, A2_ipd, A1_ipd, A0_ipd }; wire DQ15_ipd; wire DQ14_ipd; wire DQ13_ipd; wire DQ12_ipd; wire DQ11_ipd; wire DQ10_ipd; wire DQ9_ipd; wire DQ8_ipd; wire DQ7_ipd; wire DQ6_ipd; wire DQ5_ipd; wire DQ4_ipd; wire DQ3_ipd; wire DQ2_ipd; wire DQ1_ipd; wire DQ0_ipd; wire [15 : 0 ] DIn; assign DIn = { DQ15_ipd, DQ14_ipd, DQ13_ipd, DQ12_ipd, DQ11_ipd, DQ10_ipd, DQ9_ipd, DQ8_ipd, DQ7_ipd, DQ6_ipd, DQ5_ipd, DQ4_ipd, DQ3_ipd, DQ2_ipd, DQ1_ipd, DQ0_ipd }; wire [15 : 0 ] DOut; assign DOut = { DQ15, DQ14, DQ13, DQ12, DQ11, DQ10, DQ9, DQ8, DQ7, DQ6, DQ5, DQ4, DQ3, DQ2, DQ1, DQ0 }; wire CENeg_ipd; wire OENeg_ipd; wire WENeg_ipd; wire RESETNeg_ipd; wire WPNeg_ipd; wire BYTENeg_ipd; // internal delays reg START_T1; // Start TimeOut reg START_T1_in; reg CTMOUT; // Sector Erase TimeOut reg CTMOUT_in; reg READY_in; reg READY; // Device ready after reset wire DQ15_zd ; wire DQ14_zd ; wire DQ13_zd ; wire DQ12_zd ; wire DQ11_zd ; wire DQ10_zd ; wire DQ9_zd ; wire DQ8_zd ; wire DQ7_zd ; wire DQ6_zd ; wire DQ5_zd ; wire DQ4_zd ; wire DQ3_zd ; wire DQ2_zd ; wire DQ1_zd ; wire DQ0_zd ; reg [15 : 0] DOut_zd; assign {DQ15_zd, DQ14_zd, DQ13_zd, DQ12_zd, DQ11_zd, DQ10_zd, DQ9_zd, DQ8_zd, DQ7_zd, DQ6_zd, DQ5_zd, DQ4_zd, DQ3_zd, DQ2_zd, DQ1_zd, DQ0_zd } = DOut_zd; wire DQ15_Pass; wire DQ14_Pass; wire DQ13_Pass; wire DQ12_Pass; wire DQ11_Pass; wire DQ10_Pass; wire DQ9_Pass; wire DQ8_Pass; wire DQ7_Pass; wire DQ6_Pass; wire DQ5_Pass; wire DQ4_Pass; wire DQ3_Pass; wire DQ2_Pass; wire DQ1_Pass; wire DQ0_Pass; reg [15 : 0] DOut_Pass; assign {DQ15_Pass, DQ14_Pass, DQ13_Pass, DQ12_Pass, DQ11_Pass, DQ10_Pass, DQ9_Pass, DQ8_Pass, DQ7_Pass, DQ6_Pass, DQ5_Pass, DQ4_Pass, DQ3_Pass, DQ2_Pass, DQ1_Pass, DQ0_Pass } = DOut_Pass; reg RY_zd; reg POW_in ; reg POW_out; reg POB_in ; reg POB_out; reg SEO_in ; reg SEO_out; parameter UserPreload = 1'b0; parameter mem_file_name = "none"; parameter prot_file_name = "none"; parameter secsi_file_name = "none"; parameter TimingModel = "DefaultTimingModel"; parameter PartID = "s29as016j"; parameter MaxData = 255; parameter SecSize = 16'hFFFF; parameter SecSiSize = 16'hFF; parameter SecNum = 31; parameter SubSecNum = 7; parameter HiAddrBit = 19; //varibles to resolve if bottom or top architecture is used reg [20*8-1:0] tmp_timing;//stores copy of TimingModel reg [7:0] tmp_char;//stores "1" or "2" fot top /bottom boot integer found = 1'b0; // powerup reg PoweredUp; `define SPEEDSIM; //FSM control signals reg ULBYPASS ; ////Unlock Bypass Active reg OTP_ACT ; ////SecSi access reg ESP_ACT ; ////Erase Suspend reg PDONE ; ////Prog. Done reg PSTART ; ////Start Programming //Program location is in protected sector reg PERR ; reg EDONE ; ////Ers. Done reg ESTART ; ////Start Erase reg ESUSP ; ////Suspend Erase reg ERES ; ////Resume Erase //All sectors selected for erasure are protected reg EERR ; //Sectors selected for erasure reg [SecNum:0] Ers_Queue; reg [SubSecNum:0] Ers_Sub_Queue; //Command Register reg write ; reg read ; //Sector Address integer SecAddr = 0; // 0 - SecNum integer SubSect = 0; // 0 - SubSecNum integer SA = 0; // 0 TO SecNum integer SSA = 0; // 0 TO SubSecNum //Address within sector integer Address = 0; // 0 - SecSize integer SecSiAddr = 0; // 0 - SecNum //A19:A11 Don't Care integer Addr ; //0 TO 16'h7FF# //glitch protection wire gWE_n ; wire gCE_n ; wire gOE_n ; reg[7:0] old_bit, new_bit; integer old_int, new_int; integer wr_cnt; reg RST ; reg reseted ; integer Mem[0:(SecNum+1)*(SecSize+1)-1]; //Sector Protection Status reg [SecNum:0] Sec_Prot= ~(0); //Sector Protection for sub sectors reg [SubSecNum:0] SubSec_Prot =8'hFF; integer SecSi[0:SecSiSize]; integer CFI_array[16:91]; //SecSi ProtectionStatus reg FactoryProt = 0; reg Viol = 1'b0; // Address of variable size sector integer VarSect = -1; reg vs = -1; // Addresses of the Protected Sector integer ProtSecNum_1 = -1; integer ProtSecNum_2 = -1; integer WBData[0:1]; integer WBAddr[0:1]; reg oe = 1'b0; event oe_event; reg rd = 1'b0; event rd_event; reg[7:0] temp; //Status reg. reg[7:0] Status = 16'b0; // iterator for FOR loop integer i,j,k; //TPD_XX_DATA time OEDQ_t; time CEDQ_t; time OENeg_event; time CENeg_event; time ADDR_event; time ADDRDQ_t; reg FROMOE; reg FROMCE; reg FROMADDR; integer OEDQ; integer CEDQ; integer ADDRDQ; reg[15:0] TempData; /////////////////////////////////////////////////////////////////////////////// //Interconnect Path Delay Section /////////////////////////////////////////////////////////////////////////////// buf (A19_ipd, A19); buf (A18_ipd, A18); buf (A17_ipd, A17); buf (A16_ipd, A16); buf (A15_ipd, A15); buf (A14_ipd, A14); buf (A13_ipd, A13); buf (A12_ipd, A12); buf (A11_ipd, A11); buf (A10_ipd, A10); buf (A9_ipd , A9 ); buf (A8_ipd , A8 ); buf (A7_ipd , A7 ); buf (A6_ipd , A6 ); buf (A5_ipd , A5 ); buf (A4_ipd , A4 ); buf (A3_ipd , A3 ); buf (A2_ipd , A2 ); buf (A1_ipd , A1 ); buf (A0_ipd , A0 ); buf (DQ15_ipd, DQ15); buf (DQ14_ipd, DQ14); buf (DQ13_ipd, DQ13); buf (DQ12_ipd, DQ12); buf (DQ11_ipd, DQ11); buf (DQ10_ipd, DQ10); buf (DQ9_ipd , DQ9 ); buf (DQ8_ipd , DQ8 ); buf (DQ7_ipd , DQ7 ); buf (DQ6_ipd , DQ6 ); buf (DQ5_ipd , DQ5 ); buf (DQ4_ipd , DQ4 ); buf (DQ3_ipd , DQ3 ); buf (DQ2_ipd , DQ2 ); buf (DQ1_ipd , DQ1 ); buf (DQ0_ipd , DQ0 ); buf (CENeg_ipd , CENeg ); buf (OENeg_ipd , OENeg ); buf (WENeg_ipd , WENeg ); buf (RESETNeg_ipd , RESETNeg ); buf (BYTENeg_ipd , BYTENeg ); buf (WPNeg_ipd , WPNeg ); /////////////////////////////////////////////////////////////////////////////// // Propagation delay Section /////////////////////////////////////////////////////////////////////////////// nmos (DQ15, DQ15_Pass , 1); nmos (DQ14, DQ14_Pass , 1); nmos (DQ13, DQ13_Pass , 1); nmos (DQ12, DQ12_Pass , 1); nmos (DQ11, DQ11_Pass , 1); nmos (DQ10, DQ10_Pass , 1); nmos (DQ9 , DQ9_Pass , 1); nmos (DQ8 , DQ8_Pass , 1); nmos (DQ7 , DQ7_Pass , 1); nmos (DQ6 , DQ6_Pass , 1); nmos (DQ5 , DQ5_Pass , 1); nmos (DQ4 , DQ4_Pass , 1); nmos (DQ3 , DQ3_Pass , 1); nmos (DQ2 , DQ2_Pass , 1); nmos (DQ1 , DQ1_Pass , 1); nmos (DQ0 , DQ0_Pass , 1); nmos (RY , 1'b0 , ~RY_zd); wire deg; //VHDL VITAL CheckEnable equivalents wire CENeg_Check; assign CENeg_Check = CENeg; wire OENeg_Check; assign OENeg_Check = OENeg; wire WENeg_Check; assign WENeg_Check = WENeg; specify // tipd delays: interconnect path delays , mapped to input port delays. // In Verilog is not necessary to declare any tipd_ delay variables, // they can be taken from SDF file // With all the other delays real delays would be taken from SDF file // tpd delays // tpd delays specparam tpd_A0_DQ0 =1; specparam tpd_CENeg_DQ0 =1; specparam tpd_OENeg_DQ0 =1; specparam tpd_BYTENeg_DQ15 =1; specparam tpd_RESETNeg_DQ0 =1; specparam tpd_WENeg_RY =1; //tBUSY // tsetup values: setup time specparam tsetup_A0_CENeg =1; //tAS edge \ specparam tsetup_DQ0_CENeg =1; //tDS edge / specparam tsetup_CENeg_WENeg =1; //0 ns / // thold values: hold times specparam thold_A0_CENeg =1; //tAH edge \ specparam thold_DQ0_CENeg =1; //tDH edge / specparam thold_CENeg_WENeg =1; //tCH edge / specparam thold_CENeg_RESETNeg =1; //tRH edge / specparam thold_BYTENeg_CENeg =1; //telfh, tehfl \ specparam thold_OENeg_WENeg =1; //tOEH edge / // tpw values: pulse width specparam tpw_RESETNeg_negedge =1; //tRP specparam tpw_WENeg_negedge =1; //tWP specparam tpw_WENeg_posedge =1; //tWPH specparam tpw_CENeg_negedge =1; specparam tpw_CENeg_posedge =1; specparam tpw_A0_negedge =1; //tWC tRC // tdevice values: values for internal delays //Program Operation specparam tdevice_POB = 6000; //6 us; specparam tdevice_POW = 150000; //150 us; //Sector Erase Operation tWHWH2 `ifdef SPEEDSIM //Sector Erase Operation tWHWH2 specparam tdevice_SEO = 1000; // *1000 = 10 ms; `else //Sector Erase Operation tWHWH2 specparam tdevice_SEO = 10000000; //*1000 = 10 sec; `endif //SPEEDSIM //program/erase suspend timeout specparam tdevice_START_T1 = 20000; //20 us; //sector erase command sequence timeout specparam tdevice_CTMOUT = 50000; //50 us; //device ready after Hardware reset(during embeded algorithm) specparam tdevice_READY = 20000; //20 us; //tReady // If tpd values are fetched from specify block, these parameters // must change along with SDF values, SDF values change will NOT // imlicitly apply here ! // If you want tpd values to be fetched by the model itself, please // use the PLI routine approach but be shure to set parameter // DelayValues to "FROM_PLI" as default /////////////////////////////////////////////////////////////////////////////// // Input Port Delays don't require Verilog description /////////////////////////////////////////////////////////////////////////////// // Path delays // /////////////////////////////////////////////////////////////////////////////// //for RYBYNeg signal (WENeg => RY) = tpd_WENeg_RY; (CENeg => RY) = tpd_WENeg_RY; if (FROMCE) (CENeg *> DQ0) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ1) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ2) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ3) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ4) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ5) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ6) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ7) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ8) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ9) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ10) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ11) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ12) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ13) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ14) = tpd_CENeg_DQ0; if (FROMCE) (CENeg *> DQ15) = tpd_CENeg_DQ0; if (FROMOE) (OENeg *> DQ0) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ1) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ2) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ3) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ4) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ5) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ6) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ7) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ8) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ9) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ10) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ11) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ12) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ13) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ14) = tpd_OENeg_DQ0; if (FROMOE) (OENeg *> DQ15) = tpd_OENeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ0) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ1) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ2) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ3) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ4) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ5) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ6) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ7) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ8) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ9) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ10) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ11) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ12) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ13) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ14) = tpd_RESETNeg_DQ0; if (~RESETNeg) (RESETNeg *> DQ15) = tpd_RESETNeg_DQ0; //for DQ signals (A0 *> DQ0) = tpd_A0_DQ0; (A0 *> DQ1) = tpd_A0_DQ0; (A0 *> DQ2) = tpd_A0_DQ0; (A0 *> DQ3) = tpd_A0_DQ0; (A0 *> DQ4) = tpd_A0_DQ0; (A0 *> DQ5) = tpd_A0_DQ0; (A0 *> DQ6) = tpd_A0_DQ0; (A0 *> DQ7) = tpd_A0_DQ0; (A0 *> DQ8) = tpd_A0_DQ0; (A0 *> DQ9) = tpd_A0_DQ0; (A0 *> DQ10) = tpd_A0_DQ0; (A0 *> DQ11) = tpd_A0_DQ0; (A0 *> DQ12) = tpd_A0_DQ0; (A0 *> DQ13) = tpd_A0_DQ0; (A0 *> DQ14) = tpd_A0_DQ0; (A0 *> DQ15) = tpd_A0_DQ0; (A1 *> DQ0) = tpd_A0_DQ0; (A1 *> DQ1) = tpd_A0_DQ0; (A1 *> DQ2) = tpd_A0_DQ0; (A1 *> DQ3) = tpd_A0_DQ0; (A1 *> DQ4) = tpd_A0_DQ0; (A1 *> DQ5) = tpd_A0_DQ0; (A1 *> DQ6) = tpd_A0_DQ0; (A1 *> DQ7) = tpd_A0_DQ0; (A1 *> DQ8) = tpd_A0_DQ0; (A1 *> DQ9) = tpd_A0_DQ0; (A1 *> DQ10) = tpd_A0_DQ0; (A1 *> DQ11) = tpd_A0_DQ0; (A1 *> DQ12) = tpd_A0_DQ0; (A1 *> DQ13) = tpd_A0_DQ0; (A1 *> DQ14) = tpd_A0_DQ0; (A1 *> DQ15) = tpd_A0_DQ0; (A2 *> DQ0) = tpd_A0_DQ0; (A2 *> DQ1) = tpd_A0_DQ0; (A2 *> DQ2) = tpd_A0_DQ0; (A2 *> DQ3) = tpd_A0_DQ0; (A2 *> DQ4) = tpd_A0_DQ0; (A2 *> DQ5) = tpd_A0_DQ0; (A2 *> DQ6) = tpd_A0_DQ0; (A2 *> DQ7) = tpd_A0_DQ0; (A2 *> DQ8) = tpd_A0_DQ0; (A2 *> DQ9) = tpd_A0_DQ0; (A2 *> DQ10) = tpd_A0_DQ0; (A2 *> DQ11) = tpd_A0_DQ0; (A2 *> DQ12) = tpd_A0_DQ0; (A2 *> DQ13) = tpd_A0_DQ0; (A2 *> DQ14) = tpd_A0_DQ0; (A2 *> DQ15) = tpd_A0_DQ0; (A3 *> DQ0) = tpd_A0_DQ0; (A3 *> DQ1) = tpd_A0_DQ0; (A3 *> DQ2) = tpd_A0_DQ0; (A3 *> DQ3) = tpd_A0_DQ0; (A3 *> DQ4) = tpd_A0_DQ0; (A3 *> DQ5) = tpd_A0_DQ0; (A3 *> DQ6) = tpd_A0_DQ0; (A3 *> DQ7) = tpd_A0_DQ0; (A3 *> DQ8) = tpd_A0_DQ0; (A3 *> DQ9) = tpd_A0_DQ0; (A3 *> DQ10) = tpd_A0_DQ0; (A3 *> DQ11) = tpd_A0_DQ0; (A3 *> DQ12) = tpd_A0_DQ0; (A3 *> DQ13) = tpd_A0_DQ0; (A3 *> DQ14) = tpd_A0_DQ0; (A3 *> DQ15) = tpd_A0_DQ0; (A4 *> DQ0) = tpd_A0_DQ0; (A4 *> DQ1) = tpd_A0_DQ0; (A4 *> DQ2) = tpd_A0_DQ0; (A4 *> DQ3) = tpd_A0_DQ0; (A4 *> DQ4) = tpd_A0_DQ0; (A4 *> DQ5) = tpd_A0_DQ0; (A4 *> DQ6) = tpd_A0_DQ0; (A4 *> DQ7) = tpd_A0_DQ0; (A4 *> DQ8) = tpd_A0_DQ0; (A4 *> DQ9) = tpd_A0_DQ0; (A4 *> DQ10) = tpd_A0_DQ0; (A4 *> DQ11) = tpd_A0_DQ0; (A4 *> DQ12) = tpd_A0_DQ0; (A4 *> DQ13) = tpd_A0_DQ0; (A4 *> DQ14) = tpd_A0_DQ0; (A4 *> DQ15) = tpd_A0_DQ0; (A5 *> DQ0) = tpd_A0_DQ0; (A5 *> DQ1) = tpd_A0_DQ0; (A5 *> DQ2) = tpd_A0_DQ0; (A5 *> DQ3) = tpd_A0_DQ0; (A5 *> DQ4) = tpd_A0_DQ0; (A5 *> DQ5) = tpd_A0_DQ0; (A5 *> DQ6) = tpd_A0_DQ0; (A5 *> DQ7) = tpd_A0_DQ0; (A5 *> DQ8) = tpd_A0_DQ0; (A5 *> DQ9) = tpd_A0_DQ0; (A5 *> DQ10) = tpd_A0_DQ0; (A5 *> DQ11) = tpd_A0_DQ0; (A5 *> DQ12) = tpd_A0_DQ0; (A5 *> DQ13) = tpd_A0_DQ0; (A5 *> DQ14) = tpd_A0_DQ0; (A5 *> DQ15) = tpd_A0_DQ0; (A6 *> DQ0) = tpd_A0_DQ0; (A6 *> DQ1) = tpd_A0_DQ0; (A6 *> DQ2) = tpd_A0_DQ0; (A6 *> DQ3) = tpd_A0_DQ0; (A6 *> DQ4) = tpd_A0_DQ0; (A6 *> DQ5) = tpd_A0_DQ0; (A6 *> DQ6) = tpd_A0_DQ0; (A6 *> DQ7) = tpd_A0_DQ0; (A6 *> DQ8) = tpd_A0_DQ0; (A6 *> DQ9) = tpd_A0_DQ0; (A6 *> DQ10) = tpd_A0_DQ0; (A6 *> DQ11) = tpd_A0_DQ0; (A6 *> DQ12) = tpd_A0_DQ0; (A6 *> DQ13) = tpd_A0_DQ0; (A6 *> DQ14) = tpd_A0_DQ0; (A6 *> DQ15) = tpd_A0_DQ0; (A7 *> DQ0) = tpd_A0_DQ0; (A7 *> DQ1) = tpd_A0_DQ0; (A7 *> DQ2) = tpd_A0_DQ0; (A7 *> DQ3) = tpd_A0_DQ0; (A7 *> DQ4) = tpd_A0_DQ0; (A7 *> DQ5) = tpd_A0_DQ0; (A7 *> DQ6) = tpd_A0_DQ0; (A7 *> DQ7) = tpd_A0_DQ0; (A7 *> DQ8) = tpd_A0_DQ0; (A7 *> DQ9) = tpd_A0_DQ0; (A7 *> DQ10) = tpd_A0_DQ0; (A7 *> DQ11) = tpd_A0_DQ0; (A7 *> DQ12) = tpd_A0_DQ0; (A7 *> DQ13) = tpd_A0_DQ0; (A7 *> DQ14) = tpd_A0_DQ0; (A7 *> DQ15) = tpd_A0_DQ0; (A8 *> DQ0) = tpd_A0_DQ0; (A8 *> DQ1) = tpd_A0_DQ0; (A8 *> DQ2) = tpd_A0_DQ0; (A8 *> DQ3) = tpd_A0_DQ0; (A8 *> DQ4) = tpd_A0_DQ0; (A8 *> DQ5) = tpd_A0_DQ0; (A8 *> DQ6) = tpd_A0_DQ0; (A8 *> DQ7) = tpd_A0_DQ0; (A8 *> DQ8) = tpd_A0_DQ0; (A8 *> DQ9) = tpd_A0_DQ0; (A8 *> DQ10) = tpd_A0_DQ0; (A8 *> DQ11) = tpd_A0_DQ0; (A8 *> DQ12) = tpd_A0_DQ0; (A8 *> DQ13) = tpd_A0_DQ0; (A8 *> DQ14) = tpd_A0_DQ0; (A8 *> DQ15) = tpd_A0_DQ0; (A9 *> DQ0) = tpd_A0_DQ0; (A9 *> DQ1) = tpd_A0_DQ0; (A9 *> DQ2) = tpd_A0_DQ0; (A9 *> DQ3) = tpd_A0_DQ0; (A9 *> DQ4) = tpd_A0_DQ0; (A9 *> DQ5) = tpd_A0_DQ0; (A9 *> DQ6) = tpd_A0_DQ0; (A9 *> DQ7) = tpd_A0_DQ0; (A9 *> DQ8) = tpd_A0_DQ0; (A9 *> DQ9) = tpd_A0_DQ0; (A9 *> DQ10) = tpd_A0_DQ0; (A9 *> DQ11) = tpd_A0_DQ0; (A9 *> DQ12) = tpd_A0_DQ0; (A9 *> DQ13) = tpd_A0_DQ0; (A9 *> DQ14) = tpd_A0_DQ0; (A9 *> DQ15) = tpd_A0_DQ0; (A10 *> DQ0) = tpd_A0_DQ0; (A10 *> DQ1) = tpd_A0_DQ0; (A10 *> DQ2) = tpd_A0_DQ0; (A10 *> DQ3) = tpd_A0_DQ0; (A10 *> DQ4) = tpd_A0_DQ0; (A10 *> DQ5) = tpd_A0_DQ0; (A10 *> DQ6) = tpd_A0_DQ0; (A10 *> DQ7) = tpd_A0_DQ0; (A10 *> DQ8) = tpd_A0_DQ0; (A10 *> DQ9) = tpd_A0_DQ0; (A10 *> DQ10) = tpd_A0_DQ0; (A10 *> DQ11) = tpd_A0_DQ0; (A10 *> DQ12) = tpd_A0_DQ0; (A10 *> DQ13) = tpd_A0_DQ0; (A10 *> DQ14) = tpd_A0_DQ0; (A10 *> DQ15) = tpd_A0_DQ0; (A11 *> DQ0) = tpd_A0_DQ0; (A11 *> DQ1) = tpd_A0_DQ0; (A11 *> DQ2) = tpd_A0_DQ0; (A11 *> DQ3) = tpd_A0_DQ0; (A11 *> DQ4) = tpd_A0_DQ0; (A11 *> DQ5) = tpd_A0_DQ0; (A11 *> DQ6) = tpd_A0_DQ0; (A11 *> DQ7) = tpd_A0_DQ0; (A11 *> DQ8) = tpd_A0_DQ0; (A11 *> DQ9) = tpd_A0_DQ0; (A11 *> DQ10) = tpd_A0_DQ0; (A11 *> DQ11) = tpd_A0_DQ0; (A11 *> DQ12) = tpd_A0_DQ0; (A11 *> DQ13) = tpd_A0_DQ0; (A11 *> DQ14) = tpd_A0_DQ0; (A11 *> DQ15) = tpd_A0_DQ0; (A12 *> DQ0) = tpd_A0_DQ0; (A12 *> DQ1) = tpd_A0_DQ0; (A12 *> DQ2) = tpd_A0_DQ0; (A12 *> DQ3) = tpd_A0_DQ0; (A12 *> DQ4) = tpd_A0_DQ0; (A12 *> DQ5) = tpd_A0_DQ0; (A12 *> DQ6) = tpd_A0_DQ0; (A12 *> DQ7) = tpd_A0_DQ0; (A12 *> DQ8) = tpd_A0_DQ0; (A12 *> DQ9) = tpd_A0_DQ0; (A12 *> DQ10) = tpd_A0_DQ0; (A12 *> DQ11) = tpd_A0_DQ0; (A12 *> DQ12) = tpd_A0_DQ0; (A12 *> DQ13) = tpd_A0_DQ0; (A12 *> DQ14) = tpd_A0_DQ0; (A12 *> DQ15) = tpd_A0_DQ0; (A13 *> DQ0) = tpd_A0_DQ0; (A13 *> DQ1) = tpd_A0_DQ0; (A13 *> DQ2) = tpd_A0_DQ0; (A13 *> DQ3) = tpd_A0_DQ0; (A13 *> DQ4) = tpd_A0_DQ0; (A13 *> DQ5) = tpd_A0_DQ0; (A13 *> DQ6) = tpd_A0_DQ0; (A13 *> DQ7) = tpd_A0_DQ0; (A13 *> DQ8) = tpd_A0_DQ0; (A13 *> DQ9) = tpd_A0_DQ0; (A13 *> DQ10) = tpd_A0_DQ0; (A13 *> DQ11) = tpd_A0_DQ0; (A13 *> DQ12) = tpd_A0_DQ0; (A13 *> DQ13) = tpd_A0_DQ0; (A13 *> DQ14) = tpd_A0_DQ0; (A13 *> DQ15) = tpd_A0_DQ0; (A14 *> DQ0) = tpd_A0_DQ0; (A14 *> DQ1) = tpd_A0_DQ0; (A14 *> DQ2) = tpd_A0_DQ0; (A14 *> DQ3) = tpd_A0_DQ0; (A14 *> DQ4) = tpd_A0_DQ0; (A14 *> DQ5) = tpd_A0_DQ0; (A14 *> DQ6) = tpd_A0_DQ0; (A14 *> DQ7) = tpd_A0_DQ0; (A14 *> DQ8) = tpd_A0_DQ0; (A14 *> DQ9) = tpd_A0_DQ0; (A14 *> DQ10) = tpd_A0_DQ0; (A14 *> DQ11) = tpd_A0_DQ0; (A14 *> DQ12) = tpd_A0_DQ0; (A14 *> DQ13) = tpd_A0_DQ0; (A14 *> DQ14) = tpd_A0_DQ0; (A14 *> DQ15) = tpd_A0_DQ0; (A15 *> DQ0) = tpd_A0_DQ0; (A15 *> DQ1) = tpd_A0_DQ0; (A15 *> DQ2) = tpd_A0_DQ0; (A15 *> DQ3) = tpd_A0_DQ0; (A15 *> DQ4) = tpd_A0_DQ0; (A15 *> DQ5) = tpd_A0_DQ0; (A15 *> DQ6) = tpd_A0_DQ0; (A15 *> DQ7) = tpd_A0_DQ0; (A15 *> DQ8) = tpd_A0_DQ0; (A15 *> DQ9) = tpd_A0_DQ0; (A15 *> DQ10) = tpd_A0_DQ0; (A15 *> DQ11) = tpd_A0_DQ0; (A15 *> DQ12) = tpd_A0_DQ0; (A15 *> DQ13) = tpd_A0_DQ0; (A15 *> DQ14) = tpd_A0_DQ0; (A15 *> DQ15) = tpd_A0_DQ0; (A16 *> DQ0) = tpd_A0_DQ0; (A16 *> DQ1) = tpd_A0_DQ0; (A16 *> DQ2) = tpd_A0_DQ0; (A16 *> DQ3) = tpd_A0_DQ0; (A16 *> DQ4) = tpd_A0_DQ0; (A16 *> DQ5) = tpd_A0_DQ0; (A16 *> DQ6) = tpd_A0_DQ0; (A16 *> DQ7) = tpd_A0_DQ0; (A16 *> DQ8) = tpd_A0_DQ0; (A16 *> DQ9) = tpd_A0_DQ0; (A16 *> DQ10) = tpd_A0_DQ0; (A16 *> DQ11) = tpd_A0_DQ0; (A16 *> DQ12) = tpd_A0_DQ0; (A16 *> DQ13) = tpd_A0_DQ0; (A16 *> DQ14) = tpd_A0_DQ0; (A16 *> DQ15) = tpd_A0_DQ0; (A17 *> DQ0) = tpd_A0_DQ0; (A17 *> DQ1) = tpd_A0_DQ0; (A17 *> DQ2) = tpd_A0_DQ0; (A17 *> DQ3) = tpd_A0_DQ0; (A17 *> DQ4) = tpd_A0_DQ0; (A17 *> DQ5) = tpd_A0_DQ0; (A17 *> DQ6) = tpd_A0_DQ0; (A17 *> DQ7) = tpd_A0_DQ0; (A17 *> DQ8) = tpd_A0_DQ0; (A17 *> DQ9) = tpd_A0_DQ0; (A17 *> DQ10) = tpd_A0_DQ0; (A17 *> DQ11) = tpd_A0_DQ0; (A17 *> DQ12) = tpd_A0_DQ0; (A17 *> DQ13) = tpd_A0_DQ0; (A17 *> DQ14) = tpd_A0_DQ0; (A17 *> DQ15) = tpd_A0_DQ0; (A18 *> DQ0) = tpd_A0_DQ0; (A18 *> DQ1) = tpd_A0_DQ0; (A18 *> DQ2) = tpd_A0_DQ0; (A18 *> DQ3) = tpd_A0_DQ0; (A18 *> DQ4) = tpd_A0_DQ0; (A18 *> DQ5) = tpd_A0_DQ0; (A18 *> DQ6) = tpd_A0_DQ0; (A18 *> DQ7) = tpd_A0_DQ0; (A18 *> DQ8) = tpd_A0_DQ0; (A18 *> DQ9) = tpd_A0_DQ0; (A18 *> DQ10) = tpd_A0_DQ0; (A18 *> DQ11) = tpd_A0_DQ0; (A18 *> DQ12) = tpd_A0_DQ0; (A18 *> DQ13) = tpd_A0_DQ0; (A18 *> DQ14) = tpd_A0_DQ0; (A18 *> DQ15) = tpd_A0_DQ0; (A19 *> DQ0) = tpd_A0_DQ0; (A19 *> DQ1) = tpd_A0_DQ0; (A19 *> DQ2) = tpd_A0_DQ0; (A19 *> DQ3) = tpd_A0_DQ0; (A19 *> DQ4) = tpd_A0_DQ0; (A19 *> DQ5) = tpd_A0_DQ0; (A19 *> DQ6) = tpd_A0_DQ0; (A19 *> DQ7) = tpd_A0_DQ0; (A19 *> DQ8) = tpd_A0_DQ0; (A19 *> DQ9) = tpd_A0_DQ0; (A19 *> DQ10) = tpd_A0_DQ0; (A19 *> DQ11) = tpd_A0_DQ0; (A19 *> DQ12) = tpd_A0_DQ0; (A19 *> DQ13) = tpd_A0_DQ0; (A19 *> DQ14) = tpd_A0_DQ0; (A19 *> DQ15) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ0 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ1 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ2 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ3 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ4 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ5 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ6 ) = tpd_A0_DQ0; if (~BYTENeg)( DQ15 *> DQ7 ) = tpd_A0_DQ0; if (BYTENeg)( BYTENeg *> DQ8 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ9 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ10 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ11 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ12 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ13 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ14 ) = tpd_BYTENeg_DQ15; if (BYTENeg)( BYTENeg *> DQ15 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ8 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ9 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ10 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ11 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ12 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ13 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ14 ) = tpd_BYTENeg_DQ15; if (~BYTENeg)( BYTENeg *> DQ15 ) = tpd_BYTENeg_DQ15; /////////////////////////////////////////////////////////////////////////////// // Timing Violation // /////////////////////////////////////////////////////////////////////////////// $setup ( A0 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A1 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A2 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A3 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A4 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A5 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A6 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A7 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A8 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A9 , negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A10, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A11, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A12, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A13, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A14, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A15, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A16, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A17, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A18, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A19, negedge CENeg , tsetup_A0_CENeg, Viol); $setup ( A0 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A1 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A2 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A3 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A4 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A5 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A6 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A7 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A8 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A9 , negedge WENeg , tsetup_A0_CENeg,Viol); $setup ( A10, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A11, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A12, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A13, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A14, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A15, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A16, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A17, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A18, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( A19, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( DQ0 ,posedge CENeg &&& deg , tsetup_DQ0_CENeg,Viol); $setup ( DQ1 ,posedge CENeg &&& deg , tsetup_DQ0_CENeg,Viol); $setup ( DQ2 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ3 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ4 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ5 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ6 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ7 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ8 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ9 ,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ10,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ11,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ12,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ13,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ14,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ15,posedge CENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ0 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ1 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ2 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ3 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ4 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ5 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ6 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ7 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ8 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ9 ,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ10,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ11,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ12,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ13,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ14,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( DQ15,posedge WENeg &&& deg, tsetup_DQ0_CENeg,Viol); $setup ( BYTENeg, negedge WENeg , tsetup_A0_CENeg, Viol); $setup ( WENeg , negedge CENeg , tsetup_CENeg_WENeg, Viol); $setup ( CENeg , negedge WENeg , tsetup_CENeg_WENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A0 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A1 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A2 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A3 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A4 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A5 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A6 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A7 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A8 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A9 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A10 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A11 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A12 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A13 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A14 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A15 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A16 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A17 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A18 , thold_A0_CENeg, Viol); $hold (negedge CENeg &&& (WENeg===0), A19 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A0 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A1 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A2 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A3 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A4 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A5 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A6 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A7 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A8 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A9 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A10 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A11 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A12 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A13 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A14 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A15 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A16 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A17 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A18 , thold_A0_CENeg, Viol); $hold (negedge WENeg , A19 , thold_A0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ0 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ1 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ2 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ3 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ4 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ5 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ6 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ7 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ8 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ9 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ10 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ11 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ12 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ13 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ14 , thold_DQ0_CENeg, Viol); $hold (posedge CENeg &&& deg, DQ15 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ0 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ1 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ2 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ3 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ4 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ5 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ6 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ7 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ8 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ9 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ10 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ11 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ12 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ13 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ14 , thold_DQ0_CENeg, Viol); $hold (posedge WENeg &&& deg, DQ15 , thold_DQ0_CENeg, Viol); $hold ( negedge WENeg ,BYTENeg , thold_A0_CENeg, Viol); $hold ( negedge CENeg ,BYTENeg , thold_BYTENeg_CENeg, Viol); $hold ( posedge WENeg ,OENeg , thold_OENeg_WENeg, Viol); $hold ( posedge WENeg ,CENeg , thold_CENeg_WENeg, Viol); $hold ( posedge CENeg ,WENeg , thold_CENeg_WENeg, Viol); $hold ( posedge RESETNeg &&& CENeg_Check, CENeg,thold_CENeg_RESETNeg,Viol); $hold ( posedge RESETNeg &&& OENeg_Check, OENeg,thold_CENeg_RESETNeg,Viol); $hold ( posedge RESETNeg &&& WENeg_Check, WENeg,thold_CENeg_RESETNeg,Viol); $width (negedge RESETNeg, tpw_RESETNeg_negedge); $width (posedge WENeg, tpw_WENeg_posedge); $width (negedge WENeg, tpw_WENeg_negedge); $width (posedge CENeg, tpw_CENeg_posedge); $width (negedge CENeg, tpw_CENeg_negedge); $width (negedge A0, tpw_A0_negedge); endspecify ////////////////////////////////////////////////////////////////////////////// // Main Behavior Block // ////////////////////////////////////////////////////////////////////////////// // FSM states parameter RESET =6'd0; parameter Z001 =6'd1; parameter PREL_SETBWB =6'd2; parameter PREL_ULBYPASS =6'd3; parameter PREL_ULBYPASS_RESET =6'd4; parameter CFI =6'd5; parameter AS =6'd6; parameter OTP =6'd7; parameter OTP_Z001 =6'd8; parameter OTP_PREL =6'd9; parameter OTP_EXIT =6'd10; parameter OTP_A0SEEN =6'd11; parameter A0SEEN =6'd12; parameter C8 =6'd13; parameter C8_Z001 =6'd14; parameter C8_PREL =6'd15; parameter ERS =6'd16; parameter SERS =6'd17; parameter ESPS =6'd18; parameter SERS_EXEC =6'd19; parameter ESP =6'd20; parameter ESP_Z001 =6'd21; parameter ESP_PREL =6'd22; parameter ESP_CFI =6'd23; parameter ESP_A0SEEN =6'd24; parameter ESP_AS =6'd25; parameter PGMS =6'd26; reg [5:0] current_state; reg [5:0] next_state; reg rising_edge_WENeg; reg rising_edge_CENeg; reg rising_edge_write; reg rising_edge_EDONE; reg rising_edge_ESUSP; reg rising_edge_ERES; reg rising_edge_CTMOUT_out; reg rising_edge_START_T1_out; reg rising_edge_PDONE; reg rising_edge_WPNeg; reg falling_edge_WENeg; reg falling_edge_CENeg; reg falling_edge_OENeg; reg falling_edge_write; reg falling_edge_EERR; reg falling_edge_PERR; reg falling_edge_WPNeg; reg A_event; reg DIn15_event; reg BYTENeg_event; reg rising_edge_RESETNeg = 1'b0; reg falling_edge_RESETNeg = 1'b0; reg deq; always @(DIn, DOut) begin if (DIn==DOut) deq=1'b1; else deq=1'b0; end // check when data is generated from model to avoid setuphold check in // those occasions assign deg=deq; initial begin //TOP OR BOTTOM arch model is used //assumptions: //1. TimingModel has format as "S29AS016J50TFI01" // it is important that 16. character represent top / bottom boot //2. TimingModel does not have more then 20 characters tmp_timing = TimingModel;//copy of TimingModel i = 19; while ((i >= 0) && (found != 1'b1))//search for first non null character begin //i keeps position of first non null character j = 7; while ((j >= 0) && (found != 1'b1)) begin if (tmp_timing[i*8+j] != 1'd0) found = 1'b1; else j = j-1; end i = i - 1; end i = i +1; if (found)//if non null character is found begin for (j=0;j<=7;j=j+1) begin //bottom/top character is 16th //character right from first tmp_char[j] = TimingModel[(i-15)*8+j]; end end if (tmp_char == "1") begin VarSect = SecNum; vs = 1'b1; end else if (tmp_char == "2") begin VarSect = 0; vs = 1'b0; end ProtSecNum_1 = 6*vs; ProtSecNum_2 = 6*vs+1; end reg sector_prot[0:SecNum+SubSecNum+1]; // initialize memory and load preload files if any initial begin: InitMemory integer i,j; for (i=0;i<=SecNum+SubSecNum+1;i=i+1) sector_prot[i]=0; for (i=0;i<=((SecNum+1)*(SecSize+1)-1);i=i+1) Mem[i] = MaxData; for (i=0;i<=SecSiSize;i=i+1) SecSi[i]=MaxData; for (i=0;i<=SecNum;i=i+1) begin Ers_Queue = (0); Sec_Prot[i] = (0); end for (i=0;i<=SubSecNum;i=i+1) Ers_Sub_Queue = (0); SubSec_Prot = (0); //- Sector protection preload //s29as016j_prot.mem sector protect file // / - comment // @ss - stands for sector number // d - is bit to be written at Sec_Prot(ss++) // (ss is incremented at every load) if (UserPreload && !(prot_file_name == "none")) $readmemb(prot_file_name,sector_prot); // - Memory preload // s29as016j.mem memory file // // - comment // @aaaaaa - stands for sector address // dd -
is byte to be written at Mem(aaaaaa++) // (aaaaaa is incremented at every load) if (UserPreload && !(mem_file_name == "none")) $readmemh(mem_file_name,Mem); // - Secsi preload // s29as016j_secsi.mem secsi file // // - comment // @aa - stands for sector address // dd -
is byte to be written at SecSi(aa++) // (aa is incremented at every load) if (UserPreload && !(secsi_file_name == "none")) $readmemh(secsi_file_name,SecSi); FactoryProt = sector_prot[SecNum+SubSecNum+1]; //subsector protect for (i=0;i<=SubSecNum;i=i+1) begin SubSec_Prot[i] = sector_prot[i+VarSect]; end // shift if bottom boot; loaded as top boot if (VarSect == 0) for (i = SubSecNum+1 ; i< SecNum+SubSecNum+1; i=i+1) Sec_Prot[i-SubSecNum] = sector_prot[i]; else //sector protect for (i=0;i= sssa(i) && A_tmp1 <= ssea( i)) begin SubSect = i; end end CE = CENeg; Addr = A_tmp; end end end /////////////////////////////////////////////////////////////////////////// //// Timing control for the Program start Operations /////////////////////////////////////////////////////////////////////////// integer cnt_write = 0; time duration_write ; event pdone_event; always @(posedge reseted) begin PDONE = 1'b1; end always @(reseted or PSTART) begin : programming if (reseted) begin if (PSTART && PDONE) begin if (( SA != VarSect && (~Sec_Prot[SA]) && (~Ers_Queue[SA] || ~ESP_ACT ) && (FactoryProt == 0 || ~OTP_ACT ) ) || ( SA == VarSect && (~SubSec_Prot[SSA]) && (~Ers_Sub_Queue[SSA] || ~ESP_ACT) && (FactoryProt == 0 || ~OTP_ACT) )) begin if (BYTENeg) duration_write = tdevice_POW; else duration_write = tdevice_POB; PDONE = 1'b0; ->pdone_event; end else begin PERR = 1'b1; PERR <= #1000 1'b0; end end end end always @(pdone_event) begin:pdone_process PDONE = 1'b0; #duration_write PDONE = 1'b1; end ///////////////////////////////////////////////////////////////////////// // Timing control for the Erase Operations ///////////////////////////////////////////////////////////////////////// integer cnt_erase = 0; // 0 - SecNum+SubSecNum integer cnt_erase1 = 0; time elapsed_erase; time duration_erase; time start_erase; always @(posedge reseted) begin disable edone_process; EDONE = 1'b1; end event edone_event; always @(reseted or ESTART) begin: erase integer i; if (reseted) begin if (ESTART && EDONE) begin cnt_erase = 0; cnt_erase1 = 0; for (i=0;i<=SecNum;i=i+1) begin if ( i == VarSect ) begin for(j=0;j<=SubSecNum;j=j+1) begin if ((Ers_Sub_Queue[j]==1'b1) && (~SubSec_Prot[j])) cnt_erase1 = cnt_erase1 + 1; end end else begin if ((Ers_Queue[i]==1'b1) && (Sec_Prot[i]!= 1'b1)) cnt_erase = cnt_erase + 1; end end if (cnt_erase>0 || cnt_erase1>0) begin elapsed_erase = 0; duration_erase = cnt_erase* tdevice_SEO*1000 + cnt_erase1* (tdevice_SEO*1000 / 8) ; ->edone_event; start_erase = $time; end else begin EERR = 1'b1; EERR <= #100000 1'b0; end end end end always @(edone_event) begin : edone_process EDONE = 1'b0; #duration_erase EDONE = 1'b1; end always @(reseted or ESUSP) begin if (reseted) if (ESUSP && ~EDONE) begin disable edone_process; elapsed_erase = $time - start_erase; duration_erase = duration_erase - elapsed_erase; EDONE = 1'b0; end end always @(reseted or ERES) begin if (reseted) if (ERES && ~EDONE) begin start_erase = $time; EDONE = 1'b0; ->edone_event; end end //////////////////////////////////////////////////////////////////////////// //// Main Behavior Process //// combinational process for next state generation //////////////////////////////////////////////////////////////////////////// reg PATTERN_1 = 1'b0; reg PATTERN_2 = 1'b0; reg A_PAT_1 = 1'b0; //DATA High Byte integer DataHi ; //DATA Low Byte integer DataLo ; always @(falling_edge_write or rising_edge_EDONE or falling_edge_EERR or rising_edge_CTMOUT_out or rising_edge_START_T1_out or reseted or rising_edge_PDONE or falling_edge_PERR ) begin: StateGen if (falling_edge_write) begin DataLo = DIn[7:0]; if (BYTENeg) DataHi = DIn[15:8]; PATTERN_1 = (Addr==16'h555) && (DataLo==8'hAA) ; PATTERN_2 = (Addr==16'h2AA) && (DataLo==8'h55) ; A_PAT_1 = ((Addr==16'h555) && ~ULBYPASS) || ULBYPASS; end if (reseted!=1'b1) next_state = current_state; else case (current_state) RESET : begin if (falling_edge_write) begin if (PATTERN_1) next_state = Z001; else if ((Addr == 16'h55) && (DataLo==8'h98) ) next_state = CFI; else next_state = RESET; end end Z001 : begin if (falling_edge_write) begin if (PATTERN_2) next_state = PREL_SETBWB; else next_state = RESET; end end PREL_SETBWB: begin if (falling_edge_write) begin if (A_PAT_1 && (DataLo==8'hA0)) #1 next_state = A0SEEN; else if (A_PAT_1 && (DataLo==8'h20)) next_state = PREL_ULBYPASS; else if (A_PAT_1 && (DataLo==8'h90)) next_state = AS; else if (A_PAT_1 && (DataLo==8'h80)) next_state = C8; else if (A_PAT_1 && (DataLo==16'h88)) next_state = OTP; else next_state = RESET; end end PREL_ULBYPASS : begin if (falling_edge_write) begin if (A_PAT_1 && (DataLo==16'h90)) next_state = PREL_ULBYPASS_RESET; else if (A_PAT_1 && (DataLo==16'hA0)) #1 next_state = A0SEEN; else next_state = PREL_ULBYPASS; end end PREL_ULBYPASS_RESET : begin if (falling_edge_write) begin if (DataLo == 8'h00) begin if (ESP_ACT) next_state = ESP; else next_state = RESET; end else next_state = PREL_ULBYPASS; end end CFI: begin if (falling_edge_write) begin if (DataLo == 8'hF0) next_state = RESET; else next_state = CFI; end end AS : begin if (falling_edge_write) begin if (DataLo==16'hF0) next_state = RESET; else if ((Addr== 16'h55) && (DataLo == 16'h98)) next_state = CFI; else next_state = AS; end end A0SEEN: begin if (falling_edge_write) #1 next_state = PGMS; else next_state = A0SEEN; end OTP : begin if (falling_edge_write) begin if (PATTERN_1) next_state = OTP_Z001; else next_state = OTP; end end OTP_Z001 : begin if (falling_edge_write) begin if (PATTERN_2) #1 next_state = OTP_PREL; else next_state = OTP; end end OTP_PREL : begin if (falling_edge_write) begin if ((Addr == 16'h555) && (DataLo == 16'h90)) next_state = OTP_EXIT; else if ((Addr == 16'h555) && (DataLo == 16'hA0)) #1 next_state = OTP_A0SEEN; else next_state = OTP; end end OTP_EXIT: begin if (falling_edge_write) begin if (DataLo == 16'h00) begin if (ESP_ACT) next_state = ESP; else next_state = RESET; end else if (DataLo == 16'hF0) next_state = OTP; else next_state = OTP_EXIT; end end OTP_A0SEEN : begin if (falling_edge_write) #1 next_state = PGMS; else next_state = OTP_A0SEEN; end C8: begin if (falling_edge_write) begin if (PATTERN_1) next_state = C8_Z001; else next_state = RESET; end end C8_Z001: begin if (falling_edge_write) begin if (PATTERN_2) next_state = C8_PREL; else next_state = RESET; end end C8_PREL : begin if (falling_edge_write) begin if ((Addr == 16'h555) && (DataLo==16'h10)) next_state = ERS; else if (DataLo==16'h30) next_state = SERS; else next_state = RESET; end end ERS : begin if (rising_edge_EDONE || falling_edge_EERR) next_state = RESET; end SERS: begin if (rising_edge_CTMOUT_out) next_state = SERS_EXEC; else if (falling_edge_write) begin if (DataLo == 16'hB0) next_state = ESP; else if (DataLo ==16'h30) next_state = SERS; else next_state = RESET; end end ESPS: begin if (rising_edge_START_T1_out) next_state = ESP; end SERS_EXEC : begin if (rising_edge_EDONE || falling_edge_EERR) next_state = RESET; else if (EERR != 1'b1) begin if (falling_edge_write) if (DataLo == 16'hB0) next_state = ESPS; end end ESP: begin if (falling_edge_write) begin if (DataLo == 16'h30) #1 next_state = SERS_EXEC; else if ((Addr == 16'h55) && (DataLo == 16'h98)) next_state = ESP_CFI; else if (PATTERN_1) next_state = ESP_Z001; end end ESP_Z001: begin if (falling_edge_write) if (PATTERN_2) next_state = ESP_PREL; else next_state = ESP; end ESP_PREL: begin if (falling_edge_write) begin if ((Addr == 16'h555) && (DataLo == 16'hA0)) next_state = ESP_A0SEEN; else if ((Addr == 16'h555) && (DataLo == 16'h88)) next_state = OTP; else if ((Addr == 16'h555) && (DataLo == 16'h90)) next_state = ESP_AS; else if( A_PAT_1 && DataLo == 16'h20) next_state = PREL_ULBYPASS; else next_state = ESP; end end ESP_CFI: begin if (falling_edge_write) begin if (DataLo == 16'hF0) next_state = ESP; else next_state = ESP_CFI; end end ESP_AS: begin if (falling_edge_write && DataLo == 16'hF0) next_state = ESP; end ESP_A0SEEN: begin if (falling_edge_write) next_state = PGMS; end PGMS: begin if (rising_edge_PDONE || falling_edge_PERR) begin if (ESP_ACT) next_state = ESP; else if (ULBYPASS) next_state = PREL_ULBYPASS; else if (OTP_ACT) next_state = OTP; else next_state = RESET; end end endcase end /////////////////////////////////////////////////////////////////////////// //FSM Output generation and general funcionality /////////////////////////////////////////////////////////////////////////// reg corrupt = 1'b0; always @(falling_edge_write or reseted or current_state or oe or rd or rising_edge_EDONE or rising_edge_PDONE or rising_edge_CTMOUT_out or rising_edge_START_T1_out ) begin : Functional integer i,j; if (reseted) begin case (current_state) RESET : begin ESP_ACT = 0; OTP_ACT = 0; ULBYPASS = 0; CTMOUT_in = 0; if (oe || rd) MemRead(DOut_zd[15:0]); if (falling_edge_write) if ((Addr == 16'h55) && (DataLo == 16'h98)) ULBYPASS = 1'b0; RY_zd = 1'b1; end Z001 : begin end PREL_SETBWB : begin if (falling_edge_write) begin if (A_PAT_1 && (DataLo==16'h20)) ULBYPASS = 1'b1; else if (A_PAT_1 && (DataLo==16'h90)) ULBYPASS = 1'b0; else if (A_PAT_1 && (DataLo==16'h88)) begin ULBYPASS = 1'b0; OTP_ACT = 1'b1; end end end PREL_ULBYPASS: begin if (falling_edge_write) begin if (DataLo==16'h20) ULBYPASS = 1'b1; else if (A_PAT_1 && (DataLo==16'h90)) ULBYPASS = 1'b0; ESP_ACT =1'b0; end //ready signal active RY_zd = 1'b1; end PREL_ULBYPASS_RESET: begin if (falling_edge_write) begin if (DataLo==16'h00) ULBYPASS = 1'b0; end RY_zd = 1'b1; end AS: begin if (oe || rd) begin if (BYTENeg) if (Address == 0) DOut_zd[15:8] = 0; else DOut_zd[15:8] = 8'h22; else DOut_zd[15:8] = 8'bZ; if (Addr == 0) DOut_zd[7:0] = 1; else if (Addr == 1) DOut_zd[7:0] = 8'h7E; else if (Addr == 2) begin DOut_zd[7:1] = 7'b0; if ( SecAddr == VarSect ) DOut_zd[0] = SubSec_Prot[SubSect]; else DOut_zd[0] = Sec_Prot[SecAddr]; end else if (Addr == 3) begin if (VarSect > 0) begin DOut_zd[7:0] = 16'h09; if (FactoryProt == 1'b1) DOut_zd[7] = 1; end else begin DOut_zd[7:0] = 16'h11; if (FactoryProt == 1'b1) DOut_zd[7] = 1; end end else if(Addr == 16'h0E) DOut_zd[7:0] = 8'h03; else if(Addr == 16'h0F) begin if (VarSect == SecNum) DOut_zd[7:0] = 8'h04; else DOut_zd[7:0] = 8'h03; end end end A0SEEN : begin if (falling_edge_write) begin WBData[0] = -1; WBData[1] = -1; if (Viol == 1'b0) begin WBData[0] = DataLo; WBData[1] = DataHi; end Viol = 1'b0; WBAddr[0] = Address; SA = SecAddr; SSA = SubSect; PSTART = 1'b1; PSTART <= #1 1'b0; temp = DataLo; Status[7] = ~temp[7]; WBAddr[1] = -1; if (BYTENeg) WBAddr[1] = WBAddr[0] +1; end end OTP : begin OTP_ACT = 1; if (oe || rd) begin //read SecSi Sector Region if ( ((vs == 1) && (SecAddr == 31)) || ((vs == 0) && (SecAddr == 0)) ) begin SecSiAddr = Address%(SecSiSize +1); if (SecSi[SecSiAddr]==-1) DOut_zd[7:0] = 8'bx; else DOut_zd[7:0] = SecSi[SecSiAddr]; if (BYTENeg) if (SecSi[SecSiAddr+1]== -1) DOut_zd[15:8]= 8'bx; else DOut_zd[15:8] = SecSi[SecSiAddr+1]; end else $display("Invalid Address in SecSi sector"); end RY_zd = 1'b1; end OTP_PREL : begin end OTP_Z001: begin end OTP_EXIT: begin if ((falling_edge_write) && (DataLo ==16'h00)) OTP_ACT = 1'b0; end OTP_A0SEEN : begin if (falling_edge_write) begin OTP_ACT = 1'b1; PSTART = 1'b1; PSTART <= #1 1'b0; if (((vs == 1) && (SecAddr == VarSect)) || ((vs == 0) && (SecAddr == VarSect) ) ) begin WBData[0] = -1; WBData[1] = -1; if (Viol==1'b0) begin WBData[0] = DataLo; WBData[1] = DataHi; end Viol = 1'b0; WBAddr[0] = (Address % (SecSiSize + 1)) ; SA = SecAddr; SSA = SubSect; temp = DataLo; Status[7] = ~temp[7]; if (BYTENeg) WBAddr[1] = WBAddr[0] +1; else WBAddr[1] = -1; end else $display("Invalid sector Address in SecSi region", SecAddr); end end C8, C8_Z001 : begin end C8_PREL : begin if (falling_edge_write) begin if (Addr == 16'h555 && (DataLo==16'h10)) begin //Start Chip Erase ESTART = 1'b1; ESTART <= #1 1'b0; ESUSP = 1'b0; ERES = 1'b0; Ers_Queue = ~(0); Ers_Sub_Queue = 8'b11111111; Status = 8'b00001000; end else if (DataLo==16'h30) begin //put selected sector to sec. ers. queue //start timeout Ers_Queue = 0; Ers_Sub_Queue = 0; if ( SecAddr == VarSect ) Ers_Sub_Queue[SubSect] = 1'b1; else Ers_Queue[SecAddr] = 1'b1; disable TCTMOUTr; CTMOUT_in = 1'b0; #1 CTMOUT_in <= 1'b1; end end end ERS : begin if (oe || rd) begin /////////////////////////////////////////////////////////// // read status / embeded erase algorithm - Chip Erase /////////////////////////////////////////////////////////// Status[7] = 1'b0; Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[3] = 1'b1; Status[2] = ~Status[2]; //toggle DOut_zd[7:0] = Status; end if (EERR!=1'b1 ) begin if (~corrupt) begin for (i=0;i<=SecNum;i=i+1) begin if (i == VarSect) begin for( j=0;j<=SubSecNum;j=j+1) if (SubSec_Prot[j]!=1'b1) begin for(k=sssa(j);k<=ssea(j);k=k+1) Mem[sa(i)+k] = -1; end end else begin if (Sec_Prot[i]!=1'b1) for (j=0;j<=SecSize;j=j+1) begin Mem[sa(i)+j] = -1; end end end corrupt = 1; end if (rising_edge_EDONE && corrupt ) begin corrupt = 0; for (i=0;i<=SecNum;i=i+1) begin if ( i == VarSect ) begin for( j=0;j<=SubSecNum;j=j+1) if ( SubSec_Prot[j]!=1'b1 ) for(k=sssa(j);k<=ssea(j);k=k+1) Mem[sa(i)+k] = MaxData; end else begin if (Sec_Prot[i]!=1'b1) for (j=0;j<=SecSize;j=j+1) begin Mem[sa(i)+j] = MaxData; end end end end end // busy signal active RY_zd = 1'b0; end SERS : begin if (oe || rd) begin /////////////////////////////////////////////////////////// //read status - sector erase timeout /////////////////////////////////////////////////////////// Status[3] = 1'b0; DOut_zd[7:0] = Status; end if (rising_edge_CTMOUT_out) begin CTMOUT_in = 0; START_T1_in = 0; ESTART = 1; ESTART <= #1 0; ESUSP = 0; ERES = 0; end if (falling_edge_write) begin if (DataLo == 16'hB0) begin ESTART = 1'b1; ESTART <= #1 1'b0; // must start erase prior to suspend // for edone_event ESUSP = 1'b1; ESUSP <= #1 1'b0; ERES = 1'b0; ESP_ACT = 1'b1; end else if (DataLo==16'h30) begin disable TCTMOUTr; CTMOUT_in = 1'b0; #1 CTMOUT_in <= 1'b1; if ( SecAddr == VarSect ) Ers_Sub_Queue[SubSect] = 1'b1; else Ers_Queue[SecAddr] = 1'b1; end end //ready signal active RY_zd = 1'b0; end SERS_EXEC: begin if (oe ||rd) begin /////////////////////////////////////////////////// //read status erase /////////////////////////////////////////////////// if(((SecAddr == VarSect)&&(Ers_Sub_Queue[SubSect] == 1'b1)) || ((SecAddr != VarSect)&&(Ers_Queue[SecAddr]==1'b1))) Status[2] = ~Status[2]; //toggle Status[7] = 1'b0; Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[3] = 1'b1; DOut_zd[7:0] = Status; end if (falling_edge_write) begin if (~EDONE && (EERR!=1'b1)) begin if (DataLo==16'hB0) START_T1_in = 1'b1; end end if (EERR!=1'b1 && ~oe && ~rd) begin if (~rising_edge_EDONE) begin for (i=0;i<=SecNum;i=i+1) begin if ( i == VarSect) begin for( j=0;j<=SubSecNum;j=j+1) if (SubSec_Prot[j]!=1'b1 && Ers_Sub_Queue[j]==1'b1) begin for(k=sssa(j);k<=ssea(j);k=k+1) Mem[sa(i)+k] = -1; end end else begin if (Sec_Prot[i]!=1'b1 && Ers_Queue[i]) for (j=0;j<=SecSize;j=j+1) Mem[sa(i)+j] = -1; end end end if (rising_edge_EDONE) begin for (i=0;i<=SecNum;i=i+1) begin if ( i == VarSect ) begin for( j=0;j<=SubSecNum;j=j+1) if (SubSec_Prot[j]!=1'b1 && Ers_Sub_Queue[j]) for(k=sssa(j);k<=ssea(j);k=k+1) Mem[sa(i)+k] = MaxData; end else begin if (Sec_Prot[i]!=1'b1 && Ers_Queue[i]) for (j=0;j<=SecSize;j=j+1) Mem[sa(i)+j] = MaxData; end end end end //busy signal active RY_zd = 1'b0; end ESPS : begin ESUSP = 1; if (oe || rd) begin /////////////////////////////////////////////////////////// //read status / erase suspend timeout - stil erasing /////////////////////////////////////////////////////////// if (( SecAddr != VarSect && Ers_Queue[SecAddr]==1'b1) || ( SecAddr == VarSect && Ers_Sub_Queue[SubSect]==1'b1)) Status[2] = ~Status[2]; //toggle Status[7] = 1'b0; Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[3] = 1'b1; DOut_zd[7:0] = Status; end if (rising_edge_START_T1_out) begin ESP_ACT = 1'b1; START_T1_in = 1'b0; end //busy signal not active RY_zd = 1'b0; end ESP : begin ESUSP = 1'b0; if (oe || rd) begin /////////////////////////////////////////////////////////// //read /////////////////////////////////////////////////////////// if (( SecAddr != VarSect && Ers_Queue[SecAddr]!=1'b1) ||( SecAddr == VarSect && Ers_Sub_Queue[SubSect]!=1'b1)) MemRead(DOut_zd[15:0]); else begin ///////////////////////////////////////////////////// //read status /////////////////////////////////////////////////////// Status[7] = 1'b1; Status[5] = 1'b0; Status[2] = ~Status[2]; DOut_zd[7:0] = Status; end end if (falling_edge_write) begin if (DataLo==16'h30)//resume erase begin ERES = 1; ERES = #1 1'b0; ESP_ACT = 0; end end //busy signal active RY_zd = 1'b1; end ESP_Z001, ESP_PREL: begin end CFI : begin if (oe) begin DOut_zd[15:0] = 16'b0; if ((Addr >= 16'h10 && Addr <= 16'h3C) || (Addr >= 16'h40 && Addr <= 16'h50)) begin DOut_zd[7:0] = CFI_array[Addr]; end else begin DOut_zd[15:0] = 16'bZ; $display ("Invalid CFI query address"); end end end ESP_CFI: begin if (oe) begin if ((Addr >= 16'h10 && Addr <= 16'h3C) || (Addr >= 16'h40 && Addr <= 16'h50)) begin DOut_zd[7:0] = CFI_array[Addr]; DOut_zd[15:8] = 8'b0; end else begin DOut_zd[15:0] = 16'bZ; $display ("Invalid CFI query address"); end end if (falling_edge_write) begin if (DataLo==16'hF0)//resume erase ESP_ACT = 1'b1; else ESP_ACT = 1'b1; end end ESP_A0SEEN: begin if (falling_edge_write) begin ESP_ACT = 1'b1; PSTART = 1'b1; PSTART <= #1 1'b0; WBData[0] = -1; WBData[1] = -1; if (Viol==1'b0) begin WBData[0] = DataLo; WBData[1] = DataHi; end Viol = 1'b0; WBAddr[0] = Address; SA = SecAddr; SSA = SubSect; temp = DataLo; Status[7] = ~temp[7]; if (BYTENeg) WBAddr[1] = WBAddr[0] +1; else WBAddr[1] = -1; end end ESP_AS: begin if (oe || rd) begin if (BYTENeg) if (Address == 0) DOut_zd[15:8] = 0; else DOut_zd[15:8] = 8'h22; else DOut_zd[15:8] = 8'bZ; if (Addr == 0) DOut_zd[7:0] = 1; else if (Addr == 1) DOut_zd[7:0] = 8'h7E; else if (Addr == 2) begin DOut_zd[7:1] = 7'b0; if ( SecAddr == VarSect ) DOut_zd[0] = SubSec_Prot[SubSect]; else DOut_zd[0] = Sec_Prot[SecAddr]; end else if (Addr == 3) begin if (VarSect > 0) begin DOut_zd[7:0] = 16'h09; if (FactoryProt == 1'b1) DOut_zd[7] = 1; end else begin DOut_zd[7:0] = 16'h11; if (FactoryProt == 1'b1) DOut_zd[7] = 1; end end else if(Addr == 16'h0E) DOut_zd[7:0] = 8'h03; else if(Addr == 16'h0F) begin if (VarSect==SecNum) DOut_zd[7:0] = 8'h04; else DOut_zd[7:0] = 8'h03; end end end PGMS : begin if (oe || rd) begin /////////////////////////////////////////////////////////// //read status /////////////////////////////////////////////////////////// Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[1] = 1'b0; DOut_zd[7:0] = Status; end RY_zd = 1'b0; if (PERR!=1'b1 && ~falling_edge_PERR) begin //Word/Byte program wr_cnt = 0; if (WBAddr[1] > -1 ) wr_cnt =1; for (i=wr_cnt;i>=0;i=i-1) begin new_int= WBData[i]; if (~OTP_ACT) old_int=Mem[sa(SA)+WBAddr[i]]; else old_int=SecSi[WBAddr[i]]; if (new_int>-1) begin new_bit = new_int; if (old_int>-1) begin old_bit = old_int; for(j=0;j<=7;j=j+1) if (~old_bit[j]) new_bit[j]=1'b0; new_int=new_bit; end WBData[i]= new_int; end else WBData[i]= -1; end for (i=wr_cnt;i>=0;i=i-1) begin if (~OTP_ACT) Mem[sa(SA)+WBAddr[i]] = -1; else SecSi[WBAddr[i]] = -1; end if (rising_edge_PDONE && ~PERR) begin for (i=wr_cnt;i>=0;i=i-1) begin if (~OTP_ACT) Mem[sa(SA)+WBAddr[i]] = WBData[i]; else SecSi[WBAddr[i]] = WBData[i]; WBData[i]= -1; end end end end endcase end end //Output Disable Control always @(gOE_n or gCE_n or RESETNeg or RST ) begin if (gOE_n || gCE_n || (~RESETNeg && ~RST)) DOut_zd = 16'bZ; end always @(BYTENeg) begin if (~BYTENeg) DOut_zd[15:8] = 8'bZ; end reg SecProt_reg_1, SecProt_reg_2; always @(WPNeg) begin //Hardware Write Protection if (~WPNeg && PoweredUp) begin SecProt_reg_1 = SubSec_Prot[ProtSecNum_1]; SecProt_reg_2 = SubSec_Prot[ProtSecNum_2]; SubSec_Prot[ProtSecNum_1] = 1'b1; SubSec_Prot[ProtSecNum_2] = 1'b1; end else if (WPNeg && PoweredUp) begin SubSec_Prot[ProtSecNum_1] = SecProt_reg_1; SubSec_Prot[ProtSecNum_2] = SecProt_reg_2; end end always @(DOut_zd) begin : OutputGen if (DOut_zd[0] !== 1'bz) begin CEDQ_t = CENeg_event + CEDQ; ADDRDQ_t = ADDR_event + ADDRDQ; OEDQ_t = OENeg_event + OEDQ; FROMCE = ((CEDQ_t >= OEDQ_t) && ( CEDQ_t >= $time)); FROMOE = ((OEDQ_t >= CEDQ_t) && ( OEDQ_t >= $time)); FROMADDR = 1'b1; if ((ADDRDQ_t > $time )&& (((ADDRDQ_t>OEDQ_t) && FROMOE) || ((ADDRDQ_t>CEDQ_t) && FROMCE))) begin TempData = DOut_zd; FROMADDR = 1'b0; if (~BYTENeg) DOut_Pass[15:8] = 8'bz; else DOut_Pass[15:8] = 8'bx; DOut_Pass[7:0] = 8'bx; DOut_Pass <= #( ADDRDQ_t - $time ) TempData; end else DOut_Pass = DOut_zd; end end always @(DOut_zd) begin if (DOut_zd[0] === 1'bz) begin disable OutputGen; FROMCE = 1'b1; FROMOE = 1'b1; FROMADDR = 1'b0; DOut_Pass = DOut_zd; end end initial begin /////////////////////////////////////////////////////////////////////// //CFI array data /////////////////////////////////////////////////////////////////////// //CFI query identification string for (i=16;i<80;i=i+1) CFI_array[i] = -1; CFI_array[16'h10] = 16'h0051; CFI_array[16'h11] = 16'h0052; CFI_array[16'h12] = 16'h0059; CFI_array[16'h13] = 16'h0002; CFI_array[16'h14] = 16'h0000; CFI_array[16'h15] = 16'h0040; CFI_array[16'h16] = 16'h0000; CFI_array[16'h17] = 16'h0000; CFI_array[16'h18] = 16'h0000; CFI_array[16'h19] = 16'h0000; CFI_array[16'h1A] = 16'h0000; //system interface string CFI_array[16'h1B] = 16'h0017; CFI_array[16'h1C] = 16'h0019; CFI_array[16'h1D] = 16'h0000; CFI_array[16'h1E] = 16'h0000; CFI_array[16'h1F] = 16'h0003; CFI_array[16'h20] = 16'h0000; CFI_array[16'h21] = 16'h0009; CFI_array[16'h22] = 16'h0000; CFI_array[16'h23] = 16'h0005; CFI_array[16'h24] = 16'h0000; CFI_array[16'h25] = 16'h0004; CFI_array[16'h26] = 16'h0000; //device geometry definition CFI_array[16'h27] = 16'h0015; CFI_array[16'h28] = 16'h0002; CFI_array[16'h29] = 16'h0000; CFI_array[16'h2A] = 16'h0000; CFI_array[16'h2B] = 16'h0000; CFI_array[16'h2C] = 16'h0002; CFI_array[16'h2D] = 16'h0007; CFI_array[16'h2E] = 16'h0000; CFI_array[16'h2F] = 16'h0020; CFI_array[16'h30] = 16'h0000; CFI_array[16'h31] = 16'h001E; CFI_array[16'h32] = 16'h0000; CFI_array[16'h33] = 16'h0000; CFI_array[16'h34] = 16'h0001; CFI_array[16'h35] = 16'h0000; CFI_array[16'h36] = 16'h0000; CFI_array[16'h37] = 16'h0000; CFI_array[16'h38] = 16'h0000; CFI_array[16'h39] = 16'h0000; CFI_array[16'h3A] = 16'h0000; CFI_array[16'h3B] = 16'h0000; CFI_array[16'h3C] = 16'h0000; //primary vendor-specific extended query CFI_array[16'h40] = 16'h0050; CFI_array[16'h41] = 16'h0052; CFI_array[16'h42] = 16'h0049; CFI_array[16'h43] = 16'h0031; CFI_array[16'h44] = 16'h0034; CFI_array[16'h45] = 16'h000C; CFI_array[16'h46] = 16'h0002; CFI_array[16'h47] = 16'h0001; CFI_array[16'h48] = 16'h0001; CFI_array[16'h49] = 16'h0004; CFI_array[16'h4A] = 16'h0000; CFI_array[16'h4B] = 16'h0000; CFI_array[16'h4C] = 16'h0000; CFI_array[16'h4D] = 16'h0000; CFI_array[16'h4E] = 16'h0000; if (vs == 1) CFI_array[16'h4F] = 16'h0003; else if (vs == 0) CFI_array[16'h4F] = 16'h0002; CFI_array[16'h50] = 16'h0000; end function integer sa; input [15:0] sect; begin sa = sect * (SecSize + 1); end endfunction function integer sssa; input integer SubSec; begin if (SubSec == 0) sssa=16'h0000; else if (SubSec == 1) sssa=16'h2000; else if (SubSec == 2) sssa=16'h4000; else if (SubSec == 3) sssa=16'h6000; else if (SubSec == 4) sssa=16'h8000; else if (SubSec == 5) sssa=16'hA000; else if (SubSec == 6) sssa=16'hC000; else sssa=16'hE000; end endfunction function integer ssea; input integer SubSec; begin if (SubSec == 0) ssea=16'h1FFF; else if (SubSec == 1) ssea=16'h3FFF; else if (SubSec == 2) ssea=16'h5FFF; else if (SubSec == 3) ssea=16'h7FFF; else if (SubSec == 4) ssea=16'h9FFF; else if (SubSec == 5) ssea=16'hBFFF; else if (SubSec == 6) ssea=16'hDFFF; else ssea=16'hFFFF; end endfunction task MemRead; inout [15:0] DOut_zd; begin if (Mem[sa(SecAddr)+Address]==-1) DOut_zd[7:0] = 8'bx; else DOut_zd[7:0] = Mem[sa(SecAddr)+Address]; if (BYTENeg) if (Mem[sa(SecAddr)+Address+1]==-1) DOut_zd[15:8]= 8'bx; else DOut_zd[15:8] = Mem[sa(SecAddr)+Address+1]; end endtask always @(negedge RESETNeg) begin falling_edge_RESETNeg = 1'b1; #1 falling_edge_RESETNeg = 1'b0; end always @(posedge RESETNeg) begin rising_edge_RESETNeg = 1'b1; #1 rising_edge_RESETNeg = 1'b0; end always @(negedge WENeg) begin falling_edge_WENeg = 1; #1 falling_edge_WENeg = 0; end always @(negedge CENeg) begin falling_edge_CENeg = 1; #1 falling_edge_CENeg = 0; end always @(negedge OENeg) begin falling_edge_OENeg = 1; #1 falling_edge_OENeg = 0; end always @(posedge WENeg) begin rising_edge_WENeg = 1; #1 rising_edge_WENeg = 0; end always @(posedge CENeg) begin rising_edge_CENeg = 1; #1 rising_edge_CENeg = 0; end always @(posedge write) begin rising_edge_write = 1; #1 rising_edge_write = 0; end always @(negedge write) begin falling_edge_write = 1; #1 falling_edge_write = 0; end always @(posedge EDONE) begin rising_edge_EDONE = 1; #1 rising_edge_EDONE = 0; end always @(negedge EERR) begin falling_edge_EERR = 1; #1 falling_edge_EERR = 0; end always @(posedge ESUSP) begin rising_edge_ESUSP = 1'b1; #1 rising_edge_ESUSP = 1'b0; end always @(posedge ERES) begin rising_edge_ERES = 1'b1; #1 rising_edge_ERES = 1'b0; end always @(posedge CTMOUT) begin rising_edge_CTMOUT_out = 1; #1 rising_edge_CTMOUT_out = 0; end always @(posedge START_T1) begin rising_edge_START_T1_out = 1; #1 rising_edge_START_T1_out = 0; end always @(posedge PDONE) begin rising_edge_PDONE = 1; #1 rising_edge_PDONE = 0; end always @(negedge PERR) begin falling_edge_PERR = 1; #1 falling_edge_PERR = 0; end always @(posedge read) begin ->oe_event; end always @(oe_event) begin oe = 1'b1; #1 oe = 1'b0; end always @(A) begin A_event = 1'b1; #1 A_event = 1'b0; end always @(DIn[15]) begin DIn15_event = 1'b1; #1 DIn15_event = 1'b0; end always @(BYTENeg_ipd) begin BYTENeg_event = 1'b1; #1 BYTENeg_event = 1'b0; end always @(Address or SecAddr or BYTENeg) begin if (read ) ->rd_event; end always @(rd_event) begin rd = 1'b1; #1 rd = 1'b0; end reg BuffInOE, BuffInCE, BuffInADDR; wire BuffOutOE, BuffOutCE, BuffOutADDR; BUFFER BUFOE (BuffOutOE, BuffInOE); BUFFER BUFCE (BuffOutCE, BuffInCE); BUFFER BUFADDR (BuffOutADDR, BuffInADDR); initial begin BuffInOE = 1'b1; BuffInCE = 1'b1; BuffInADDR = 1'b1; end always @(posedge BuffOutOE) begin OEDQ = $time; end always @(posedge BuffOutCE) begin CEDQ = $time; end always @(posedge BuffOutADDR) begin ADDRDQ = $time; end endmodule module BUFFER (OUT,IN); input IN; output OUT; buf ( OUT, IN); endmodule