////////////////////////////////////////////////////////////////////////////// // File name : s29xs064r.v ////////////////////////////////////////////////////////////////////////////// // Copyright (C) 2008 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 B.Colakovic 08 October 28 Initial Release // ////////////////////////////////////////////////////////////////////////////// // PART DESCRIPTION: // // Library: FLASH // Technology: FLASH MEMORY // Part: S29XS064R // // Description: 64Mbit (4M x16-Bit) Simultaneous operation, Burst mode, // Top boot sector ////////////////////////////////////////////////////////////////////////////// // Known Bugs: // ////////////////////////////////////////////////////////////////////////////// // Comments : // For correct simulation, simulator resolution should be set to 1 ps // 16th character in TimingModel determines whether top or bottom boot // architecture is used ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // MODULE DECLARATION // ////////////////////////////////////////////////////////////////////////////// `timescale 1 ps/1 ps //////////////////////////////////////////////// // Top level module, FLASH as instance //////////////////////////////////////////////// module s29xs064r ( A21 , A20 , A19 , A18 , A17 , A16 , ADQ15 , ADQ14 , ADQ13 , ADQ12 , ADQ11 , ADQ10 , ADQ9 , ADQ8 , ADQ7 , ADQ6 , ADQ5 , ADQ4 , ADQ3 , ADQ2 , ADQ1 , ADQ0 , CENeg , AVDNeg , OENeg , WENeg , RESETNeg , CLK , Vpp , RDY ); //////////////////////////////////////////////////////////////////////// // Port / Part Pin Declarations //////////////////////////////////////////////////////////////////////// input A21 ; input A20 ; input A19 ; input A18 ; input A17 ; input A16 ; inout ADQ15 ; inout ADQ14 ; inout ADQ13 ; inout ADQ12 ; inout ADQ11 ; inout ADQ10 ; inout ADQ9 ; inout ADQ8 ; inout ADQ7 ; inout ADQ6 ; inout ADQ5 ; inout ADQ4 ; inout ADQ3 ; inout ADQ2 ; inout ADQ1 ; inout ADQ0 ; input CENeg ; input AVDNeg ; input OENeg ; input WENeg ; input RESETNeg ; input CLK ; input Vpp ; output RDY ; // interconnect path delay signals wire ADQ15_ipd ; wire ADQ14_ipd ; wire ADQ13_ipd ; wire ADQ12_ipd ; wire ADQ11_ipd ; wire ADQ10_ipd ; wire ADQ9_ipd ; wire ADQ8_ipd ; wire ADQ7_ipd ; wire ADQ6_ipd ; wire ADQ5_ipd ; wire ADQ4_ipd ; wire ADQ3_ipd ; wire ADQ2_ipd ; wire ADQ1_ipd ; wire ADQ0_ipd ; wire [15 : 0] A; assign A = { ADQ15_ipd, ADQ14_ipd, ADQ13_ipd, ADQ12_ipd, ADQ11_ipd, ADQ10_ipd, ADQ9_ipd, ADQ8_ipd, ADQ7_ipd, ADQ6_ipd, ADQ5_ipd, ADQ4_ipd, ADQ3_ipd, ADQ2_ipd, ADQ1_ipd, ADQ0_ipd }; wire [15 : 0 ] DIn; assign DIn = {ADQ15_ipd, ADQ14_ipd, ADQ13_ipd, ADQ12_ipd, ADQ11_ipd, ADQ10_ipd, ADQ9_ipd, ADQ8_ipd, ADQ7_ipd, ADQ6_ipd, ADQ5_ipd, ADQ4_ipd, ADQ3_ipd, ADQ2_ipd, ADQ1_ipd, ADQ0_ipd }; wire [15 : 0 ] DOut; assign DOut = {ADQ15, ADQ14, ADQ13, ADQ12, ADQ11, ADQ10, ADQ9, ADQ8, ADQ7, ADQ6, ADQ5, ADQ4, ADQ3, ADQ2, ADQ1, ADQ0 }; wire CENeg_ipd ; wire CSNeg_ipd ; wire AVDNeg_ipd ; wire OENeg_ipd ; wire WENeg_ipd ; wire RESETNeg_ipd ; wire CLK_ipd ; wire Vpp_ipd ; 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 ; 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_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; 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 RDY_zd; parameter UserPreload = 1'b0; parameter mem_file_name = "none"; parameter secsi_file_name = "none"; parameter TimingModel = "DefaultTimingModel"; parameter MemSize = 24'h3FFFFF; parameter PartID = "s29vs064r"; parameter MaxData = 16'hffff; parameter SecNum = 130; parameter BankNum = 3; parameter SecGroupNum = 1; parameter SecSize64 = 16'h7fff; parameter SecSize16 = 16'h1fff; parameter BankSize = 20'hfffff; parameter HiAddrBit = 21; parameter WrBuffLength = 31; parameter WrBuffPgNum = 19'h1ffff; parameter Reserved0 = 0; parameter Reserved1 = 1; // If speedsimulation is needed uncomment following line // `define SPEEDSIM; parameter SYNCR = 4'd0; parameter NOSYNC = 4'd1; parameter LINEAR = 4'd2; parameter CONTINUOUS = 4'd3; // FSM states parameter RESET = 8'd0; parameter Z001 = 8'd1; parameter PREL_SETBWB = 8'd2; parameter CFI = 8'd3; parameter AS = 8'd4; parameter AS_CFI = 8'd5; parameter CR_ENTRY_SET = 8'd6; parameter CR_ENTRY_RD = 8'd7; parameter LOCKREG_CMDSET = 8'd8; parameter LOCKREG_A0SEEN = 8'd9; parameter EXIT_LOCKREG = 8'd10; parameter DYB_CMDSET = 8'd11; parameter DYB_SETCLEAR = 8'd12; parameter EXIT_DYB = 8'd13; parameter A0SEEN = 8'd14; parameter OTP = 8'd15; parameter OTP_Z001 = 8'd16; parameter OTP_PREL = 8'd17; parameter OTP_EXIT = 8'd18; parameter OTP_A0SEEN = 8'd19; parameter C8 = 8'd20; parameter C8_Z001 = 8'd21; parameter C8_PREL = 8'd22; parameter ERS = 8'd23; parameter ESPS = 8'd24; parameter SERS_EXEC = 8'd25; parameter ESP = 8'd26; parameter ESP_Z001 = 8'd27; parameter ESP_PREL = 8'd28; parameter ESP_CFI = 8'd29; parameter ESP_A0SEEN = 8'd30; parameter ESP_AS = 8'd31; parameter PGMS = 8'd32; parameter PSPS = 8'd33; parameter PSP = 8'd34; parameter WR2BUFF_CNT = 8'd35; parameter WR2BUFF_LSTA = 8'd36; parameter WR2BUFF_LOAD = 8'd37; parameter WR2BUFF_CONFB = 8'd38; parameter WR2BUFF_ABORT = 8'd39; parameter WR2BUFF_Z001 = 8'd40; parameter WR2BUFF_PREL = 8'd41; parameter PSP_Z001 = 8'd42; parameter PSP_PREL = 8'd43; parameter PSP_AS = 8'd44; parameter PSP_CFI = 8'd45; // states reg [9:0] current_state = RESET; reg [9:0] next_state = RESET; reg [7:0] RD_MODE = SYNCR; reg PoweredUp = 0; //varaibles 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; integer found = 1'b0; // FSM control signals reg ESP_ACT = 0; reg LOCK_ACT = 0; reg OTP_ACT = 0; reg PSP_ACT = 0; //number of location to be writen in Write Buffer: 0-31 bytes. //if 32 word programming integer PCNT = 0; integer LCNT = 0; //Load Counter reg PDONE = 1; // Programming done reg PSTART = 0; // Start programming reg PSUSP = 0; // suspend programming reg PRES = 0; // Resume Programming reg PERR = 0; // Program location is in protected sector reg EDONE = 1; // Erase Done reg ESTART = 0; // Start Erase reg ESUSP = 0; // Suspend Erase reg ERES = 0; // Resume Erase reg EERR = 0; // All sectors selected for erasure are protected reg CEDONE = 1; // Chip Erase Done reg WRITE = 1; reg READ = 1; reg BURST = 1; reg ReadINIT = 1; reg [15:0] UNDEFINED = 16'b0; reg [15:0] OutputD, DOut_burst; reg [15:0] UpperAddress = 16'b0; // internal delays reg IACC_in = 0; // Initial access delay reg IACC_out = 0; reg START_in = 0; // Program/Erase suspend reg START_out = 0; // Timeout reg RST_in = 0; // Hardware Reset Timeout reg RST_out = 1; // Access time variables reg FROMCE = 0; reg FROMOE = 0; integer OEDQ_01; integer CEDQ_01; integer ADDRDQINasyn_01; integer ADDRDQINsyn_01; time OEDQ_t = 0; time CEDQ_t = 0; time ADDRDQ_t = 0; time ADDR_event = 0; reg[15:0] TempData; reg[15:0] tempLo; reg[7:0] temp; integer Addr, SecAddr, BankID, BurstSec,BurstBank; reg [3:0] addr_bit; // Write page buffer address integer BuffPageAddr; integer sgsaT [0:SecGroupNum]; integer sgsaB [0:SecGroupNum]; // Data integer D_tmp, BA_ERS, BA_PGM, BA_AS,BA_DYB; integer SA_PGM, SA_ERS; integer WBPage, WBSequentialAddr; reg WB_FLAG = 0; reg BF_FLAG = 0; reg OTP_REG1 = 0; reg OTP_REG2 = 0; reg CHIP_ERS_FLAG = 0; reg SECT_ERS_FLAG = 0; // glitch protection reg gWE_n = 1; reg gCE_n = 1; reg gOE_n = 1; reg AddrRef = 0; reg CLKMerge = 0; reg IN_W_ELAPSED; reg DATA_DELAY; reg rd = 1; time CLK_PER ; time LAST_CLK; reg BurstStarted; reg SYN = 0; // synchronous mode //Sector Protection Status reg[SecNum:0] DYB; //reset timing reg RST = 0; reg reseted = 0; parameter WB = 2'd0; parameter BF = 2'd1; parameter SW = 2'd2; reg [1:0] progMode = WB; parameter Mem_T = 4'd0; parameter SS_T = 4'd1; parameter AS_T = 4'd2; parameter CFI_T = 4'd3; reg [7:0] ReadTarget; parameter MEMORY =3'h0; parameter OTP_MEM =3'h1; parameter LREG =3'h2; reg [2:0] PGMS_FLAG; integer SecSiMem [0 : 255]; integer CFIMem [10 : 91]; integer Mem [0:MemSize]; reg [15:0] ConfReg0 = 16'b1010111111001000; reg [15:0] LockReg = 16'b1111111111111111; // write buffer signals integer BurstDelay, WS_Initial; integer WBData[0:31]; integer WBAddr[0:31]; integer WPage; reg Check_freq; // timing check violation reg Viol = 1'b0; integer BurstAddr,RDCnt,WS_Boundary; integer DelayCycSwitch,WS_Latency; integer cnt = 0; integer cnt16 = 0; integer cnt64 = 0; reg D_pass = 1; reg PATTERN_1 = 0; reg PATTERN_2 = 0; reg A_PAT_1 = 0; reg RDY_temp; reg deq; reg FlagOE=1; reg FlagBURST=1; /////////////////////////////////////////////////////////////////////////////// //Interconnect Path Delay Section /////////////////////////////////////////////////////////////////////////////// buf (ADQ15_ipd, ADQ15); buf (ADQ14_ipd, ADQ14); buf (ADQ13_ipd, ADQ13); buf (ADQ12_ipd, ADQ12); buf (ADQ11_ipd, ADQ11); buf (ADQ10_ipd, ADQ10); buf (ADQ9_ipd , ADQ9 ); buf (ADQ8_ipd , ADQ8 ); buf (ADQ7_ipd , ADQ7 ); buf (ADQ6_ipd , ADQ6 ); buf (ADQ5_ipd , ADQ5 ); buf (ADQ4_ipd , ADQ4 ); buf (ADQ3_ipd , ADQ3 ); buf (ADQ2_ipd , ADQ2 ); buf (ADQ1_ipd , ADQ1 ); buf (ADQ0_ipd , ADQ0 ); buf (CENeg_ipd , CENeg ); buf (AVDNeg_ipd , AVDNeg ); buf (OENeg_ipd , OENeg ); buf (WENeg_ipd , WENeg ); buf (RESETNeg_ipd , RESETNeg ); buf (CLK_ipd , CLK ); buf (Vpp_ipd , Vpp ); /////////////////////////////////////////////////////////////////////////////// // Propagation delay Section /////////////////////////////////////////////////////////////////////////////// nmos (ADQ15, DQ15_Pass , 1); nmos (ADQ14, DQ14_Pass , 1); nmos (ADQ13, DQ13_Pass , 1); nmos (ADQ12, DQ12_Pass , 1); nmos (ADQ11, DQ11_Pass , 1); nmos (ADQ10, DQ10_Pass , 1); nmos (ADQ9 , DQ9_Pass , 1); nmos (ADQ8 , DQ8_Pass , 1); nmos (ADQ7 , DQ7_Pass , 1); nmos (ADQ6 , DQ6_Pass , 1); nmos (ADQ5 , DQ5_Pass , 1); nmos (ADQ4 , DQ4_Pass , 1); nmos (ADQ3 , DQ3_Pass , 1); nmos (ADQ2 , DQ2_Pass , 1); nmos (ADQ1 , DQ1_Pass , 1); nmos (ADQ0 , DQ0_Pass , 1); nmos (RDY , RDY_zd , 1); wire deg; // Needed for TimingChecks // VHDL CheckEnable Equivalent wire Check_ADQ0_CLK; assign Check_ADQ0_CLK = ~CENeg && SYN && ~AVDNeg; wire Check_ADQ0_AVDNeg; assign Check_ADQ0_AVDNeg = ~CENeg; wire Check_ADQ0_WENeg; assign Check_ADQ0_WENeg = ~CENeg && ~deg; wire RDY_EQU_0; assign Check_OENeg_WENeg = ~PDONE || ~EDONE; wire RDY_EQU_1; assign Check_OENeg_WENeg = PDONE && EDONE; wire Check_AVDNeg_CLK; assign Check_AVDNeg_CLK = ~CENeg && ~AVDNeg && SYN; wire Check_CENeg_CLK; assign Check_CENeg_CLK = SYN && ~AVDNeg && 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 specparam tpd_RESETNeg_ADQ0 = 1; specparam tpd_CENeg_ADQ0_SYN_EQ_0 = 1; specparam tpd_CENeg_ADQ0_SYN_EQ_1 = 1; specparam tpd_OENeg_ADQ0_SYN_EQ_0 = 1; specparam tpd_OENeg_ADQ0_SYN_EQ_1 = 1; specparam tpd_CLK_ADQ0 = 1; specparam tpd_OENeg_RDY = 1; specparam tpd_CLK_RDY = 1; specparam tpd_CENeg_RDY_SYN_EQ_0 = 1; specparam tpd_CENeg_RDY_SYN_EQ_1 = 1; // tsetup values specparam tsetup_CENeg_CLK = 1; // tces edge / specparam tsetup_CENeg_WENeg = 1; // tcs edge \ specparam tsetup_A16_AVDNeg = 1; // tas edge / specparam tsetup_ADQ0_WENeg = 1; // tds edge / specparam tsetup_OENeg_WENeg = 1; // tweh edge \ specparam tsetup_AVDNeg_CLK = 1; // tavds edge / specparam tsetup_ADQ0_CLK = 1; // tacs edge / specparam tsetup_AVDNeg_OENeg = 1; // tavdo edge \ specparam tsetup_AVDNeg_WENeg = 1; // tvlwh edge / specparam tsetup_ADQ0_CENeg = 1; // thold values specparam thold_A16_AVDNeg = 1; // tah / specparam thold_ADQ0_WENeg = 1; // tdh edge / specparam thold_ADQ0_CLK = 1; // tach edge / specparam thold_CENeg_RESETNeg = 1; // trh edge / specparam thold_OENeg_RESETNeg = 1; // trh edge / specparam thold_CENeg_WENeg = 1; // twh edge / specparam thold_AVDNeg_CLK = 1; // tavd edge / specparam thold_OENeg_WENeg_RDY_EQU_1 = 1; //tOEH edge / specparam thold_OENeg_WENeg_RDY_EQU_0 = 1; //tOEH edge / specparam thold_ADQ0_CENeg = 1; // tpw values: pulse width specparam tpw_RESETNeg_negedge = 1; // trp specparam tpw_AVDNeg_negedge = 1; // tavdp specparam tpw_WENeg_negedge = 1; // twp specparam tpw_WENeg_posedge = 1; // twph specparam tpw_CLK_negedge = 1; // tcl specparam tpw_CLK_posedge = 1; // tch // tperiod values specparam tperiod_WENeg = 1; // twc specparam tperiod_CLK = 1; // tclk `ifdef SPEEDSIM specparam tdevice_POW = 130000000; // Program Operation per CL specparam tdevice_WRBO = 9400000; // Write Buffer Program specparam tdevice_SEO16 = 350000; // Sector Erase Operation specparam tdevice_SEO64 = 800000; // Sector Erase Operation specparam tdevice_START = 30000000;//Program/Erase Suspend specparam tdevice_IACC = 80000; //Initial access delay tIACC `else specparam tdevice_POW = 130000000; // Program Operation per CL specparam tdevice_WRBO = 9400000; // Write Buffer Program specparam tdevice_SEO16 = 350000000; // Sector Erase Operation specparam tdevice_SEO64 = 800000000; // Sector Erase Operation specparam tdevice_START = 30000000;//Program/Erase Suspend specparam tdevice_IACC = 80000; //Initial access delay tIACC `endif /////////////////////////////////////////////////////////////////////////////// // Input Port Delays don't require Verilog description /////////////////////////////////////////////////////////////////////////////// // Path delays // /////////////////////////////////////////////////////////////////////////////// // Data ouptut paths if (~RESETNeg) ( RESETNeg => ADQ0 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ1 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ2 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ3 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ4 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ5 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ6 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ7 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ8 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ9 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ10 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ11 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ12 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ13 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ14 ) = tpd_RESETNeg_ADQ0; if (~RESETNeg) ( RESETNeg => ADQ15 ) = tpd_RESETNeg_ADQ0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ0) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ1) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ2) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ3) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ4) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ5) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ6) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ7) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ8) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ9) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ10) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ11) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ12) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ13) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ14) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~SYN)(CENeg => ADQ15) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ0) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ1) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ2) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ3) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ4) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ5) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ6) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ7) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ8) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ9) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ10) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ11) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ12) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ13) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ14) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && SYN)(CENeg => ADQ15) = tpd_CENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~SYN) (OENeg => ADQ0) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ1) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ2) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ3) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ4) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ5) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ6) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ7) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ8) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ9) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ10) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ11) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ12) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ13) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ14) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~SYN) (OENeg => ADQ15) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && SYN) (OENeg => ADQ0) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ1) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ2) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ3) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ4) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ5) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ6) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ7) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ8) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ9) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ10) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ11) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ12) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ13) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ14) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && SYN) (OENeg => ADQ15) = tpd_OENeg_ADQ0_SYN_EQ_1; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ0) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ1) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ2) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ3) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ4) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ5) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ6) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ7) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ8) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ9) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ10) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ11) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ12) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ13) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ14) = tpd_CLK_ADQ0; if (~CENeg && SYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ15) = tpd_CLK_ADQ0; if ( ~CENeg && SYN ) ( OENeg => RDY ) = tpd_OENeg_RDY; if ( ~CENeg && SYN && CLK && RDY_zd !== 1'bz) ( CLK => RDY ) = tpd_CLK_RDY; if (~SYN ) (CENeg => RDY) = tpd_CENeg_RDY_SYN_EQ_0; if (SYN) (CENeg => RDY) = tpd_CENeg_RDY_SYN_EQ_1; /////////////////////////////////////////////////////////////////////////////// // Timing Violation / /////////////////////////////////////////////////////////////////////////////// $setup ( ADQ0 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ1 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ2 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ3 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ4 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ5 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ6 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ7 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ8 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ9 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ10 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ11 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ12 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ13 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ14 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $setup ( ADQ15 ,posedge CLK &&& Check_ADQ0_CLK ,tsetup_ADQ0_CLK,Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ0 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ1 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ2 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ3 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ4 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ5 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ6 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ7 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ8 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ9 ,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ10,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ11,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ12,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ13,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ14,thold_ADQ0_CLK, Viol); $hold ( posedge CLK &&& Check_ADQ0_CLK , ADQ15,thold_ADQ0_CLK, Viol); $setup ( ADQ0 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ1 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ2 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ3 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ4 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ5 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ6 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ7 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ8 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ9 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ10 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ11 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ12 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ13 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ14 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $setup ( ADQ15 , posedge AVDNeg &&& Check_ADQ0_AVDNeg, tsetup_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ0 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ1 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ2 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ3 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ4 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ5 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ6 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ7 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ8 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ9 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ10 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ11 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ12 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ13 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ14 , thold_A16_AVDNeg, Viol); $hold ( posedge AVDNeg &&& Check_ADQ0_AVDNeg, ADQ15 , thold_A16_AVDNeg, Viol); $setup ( ADQ0 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ1 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ2 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ3 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ4 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ5 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ6 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ7 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ8 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ9 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ10 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ11 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ12 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ13 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ14 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ15 , posedge WENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_WENeg, Viol); $setup ( ADQ0 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ1 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ2 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ3 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ4 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ5 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ6 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ7 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ8 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ9 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ10 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ11 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ12 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ13 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ14 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $setup ( ADQ15 , posedge CENeg &&& Check_ADQ0_WENeg, tsetup_ADQ0_CENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ0 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ1 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ2 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ3 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ4 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ5 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ6 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ7 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ8 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ9 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ10 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ11 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ12 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ13 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ14 , thold_ADQ0_WENeg, Viol); $hold ( posedge WENeg &&& Check_ADQ0_WENeg, ADQ15 , thold_ADQ0_WENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ0 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ1 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ2 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ3 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ4 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ5 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ6 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ7 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ8 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ9 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ10 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ11 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ12 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ13 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ14 , thold_ADQ0_CENeg, Viol); $hold ( posedge CENeg &&& Check_ADQ0_WENeg, ADQ15 , thold_ADQ0_CENeg, Viol); $setup ( AVDNeg ,posedge CLK &&& Check_AVDNeg_CLK, tsetup_AVDNeg_CLK, Viol); $hold ( posedge CLK &&& Check_AVDNeg_CLK, AVDNeg , thold_AVDNeg_CLK, Viol); $setup ( CENeg , posedge CLK &&& Check_CENeg_CLK, tsetup_CENeg_CLK, Viol); $setup ( CENeg , negedge WENeg, tsetup_CENeg_WENeg, Viol); $hold ( negedge WENeg , CENeg, thold_CENeg_WENeg, Viol); $setup ( OENeg , negedge WENeg, tsetup_OENeg_WENeg, Viol); $setup ( AVDNeg , negedge OENeg, tsetup_AVDNeg_OENeg, Viol); $setup ( AVDNeg , posedge WENeg, tsetup_AVDNeg_WENeg, Viol); $hold ( posedge WENeg &&& RDY_EQU_1 ,OENeg , thold_OENeg_WENeg_RDY_EQU_1 ,Viol); $hold ( posedge WENeg &&& RDY_EQU_0 ,OENeg , thold_OENeg_WENeg_RDY_EQU_0,Viol); $hold ( posedge RESETNeg, CENeg , thold_CENeg_RESETNeg, Viol); $hold ( posedge RESETNeg, OENeg , thold_OENeg_RESETNeg, Viol); $width (negedge RESETNeg, tpw_RESETNeg_negedge); $width (negedge AVDNeg , tpw_AVDNeg_negedge); $width (posedge WENeg , tpw_WENeg_posedge); $width (negedge WENeg , tpw_WENeg_negedge); $width (posedge CLK , tpw_CLK_posedge); $width (negedge CLK , tpw_CLK_negedge); $period(negedge CLK, tperiod_CLK); $period(posedge CLK, tperiod_CLK); $period(negedge WENeg, tperiod_WENeg); $period(posedge WENeg, tperiod_WENeg); endspecify //tdevice parameters aligned to model timescale //32bits exceeded time tdevice_SEO16_ts = tdevice_SEO16 * 1000; time tdevice_SEO64_ts = tdevice_SEO64 * 1000; //////////////////////////////////////////////////////////////////////////////// // Main Behavior Block // //////////////////////////////////////////////////////////////////////////////// integer AddressLatched, WrAddressLatched; reg READCYCLE, LATCHED; reg READ_END = 1; reg FRST_L = 1; reg [(HiAddrBit-16):0] HiAddr; time elapsed, duration, start, wrbo, wrbo_bf, pow,seo16, seo64; integer i, j,k, Data, DataLo, AddrCom, new_int; reg [16:0] new_bit; reg BURST_TR, SYNCREAD; reg oe = 0; reg ER_FLAG = 0; reg BOUNDARY_CROSS, BURST_END, NO_PROGRESS,BusyBound; integer BurstLength, DelayCyc_CNT, LatencyAddr; integer old_int, old_bit, wr_cnt; reg INITIAL = 0; reg [15:0] Status = 16'b0000000000000000; reg rising_edge_AVDNeg, falling_edge_AVDNeg; reg rising_edge_gWE_n, falling_edge_gWE_n; reg rising_edge_gCE_n, falling_edge_gCE_n; reg rising_edge_CENeg, falling_edge_CENeg; reg rising_edge_gOE_n, falling_edge_gOE_n; reg rising_edge_OENeg ,falling_edge_OENeg; reg rising_edge_CLK, A_event, Din_event, rising_edge_CLKMerge; reg rising_edge_RESETNeg, falling_edge_RESETNeg,rising_edge_RST_in = 0; reg rising_edge_START_in, rising_edge_READ, falling_edge_READ; reg rising_edge_reseted, rising_edge_PSTART; reg rising_edge_PSUSP, rising_edge_PRES; reg rising_edge_ESTART, rising_edge_ESUSP, rising_edge_ERES; reg falling_edge_WRITE = 0; reg rising_edge_EDONE, rising_edge_PDONE; reg rising_edge_START_out, falling_edge_RST, falling_edge_BURST; reg falling_edge_EERR, EERR_EVENT, PERR_EVENT = 0; reg next_state_event, falling_edge_ReadINIT; time OENeg_event = 0; time CENeg_event = 0; reg falling_edge_PERR = 0; reg rising_edge_PERR = 0; reg PR_FLAG = 0; integer BoundarySwitch; // Power Up time tVCS is 1 ms initial begin : PowerupTime PoweredUp = 1'b0; #1000000000 PoweredUp = 1'b1; sgsaT[0] = 30'h000000; sgsaT[1] = 30'h3f8000; sgsaB[0] = 20'h0000; sgsaB[1] = 20'h8000; end // initialize memory and load preoload files if any initial begin: InitMemory integer i,j; integer secsi[0:8'hFF]; tmp_timing = 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 if (found)//if non null character is found begin for (j=0;j<=7;j=j+1) begin tmp_char[j] = tmp_timing[(i-14)*8+j]; end end for (i=0;i<=8'hFF;i=i+1) begin secsi[i]=MaxData; end for (i=0;i<=MemSize;i=i+1) begin Mem[i]=MaxData; end if (UserPreload && !(mem_file_name == "none")) begin $readmemh(mem_file_name,Mem); end if (UserPreload && !(secsi_file_name == "none")) begin $readmemh(secsi_file_name,secsi); end //SecSi Preload for (i=0;i<=8'hFF;i=i+1) begin SecSiMem[i] = secsi[i]; end end // Process for RDY generation always @(RDY_temp, CENeg, reseted) begin : RDYGenerate if (~CENeg && ~ConfReg0[15] && reseted) if (ConfReg0[10]) RDY_zd = RDY_temp; else RDY_zd = ~RDY_temp; else if (~CENeg && reseted) RDY_zd = 1; else RDY_zd = 1'bz; end //////////////////////////////////////////////////////////////////////////// //// obtain 'LAST_EVENT information //////////////////////////////////////////////////////////////////////////// always @(negedge OENeg) begin OENeg_event = $time; end always @(negedge CENeg) begin CENeg_event = $time; end ////////////////////////////////////////////////////////// // Output Data Gen ////////////////////////////////////////////////////////// always @(DOut_zd) begin : OutputGen if (DOut_zd[0] !== 1'bz) begin if (ConfReg0[15] == 1) begin CEDQ_t = CENeg_event + CEDQ_01; OEDQ_t = OENeg_event + OEDQ_01; ADDRDQ_t = ADDR_event + ADDRDQINasyn_01; end else begin CEDQ_t = CENeg_event + CEDQ_01; OEDQ_t = OENeg_event + OEDQ_01; ADDRDQ_t = ADDR_event + ADDRDQINsyn_01; end FROMCE = ((CEDQ_t > OEDQ_t) && ( CEDQ_t >= $time)); FROMOE = ((OEDQ_t >= CEDQ_t) && ( OEDQ_t >= $time)); if ((ADDRDQ_t > $time )&& (((ADDRDQ_t > OEDQ_t) && FROMOE) || ((ADDRDQ_t > CEDQ_t) && FROMCE))) begin TempData = DOut_zd; DOut_Pass = 16'bx; #( ADDRDQ_t - $time ) DOut_Pass = TempData; end else if ((OEDQ_t < $time && CEDQ_t < $time ) && (ADDRDQ_t > $time )) begin TempData = DOut_zd; #( ADDRDQ_t - $time ) DOut_Pass = TempData; end else begin DOut_Pass = DOut_zd; end end end always @(DOut_zd) begin if (DOut_zd[0] === 1'bz) begin disable OutputGen; FROMCE = 1'b1; FROMOE = 1'b1; DOut_Pass = 16'bz; end end always @(DOut_Pass) begin if (DOut_Pass[0] != 1 && DOut_Pass[0] != 0 && DOut_Pass[0] !== 1'bz) D_pass = 1; else D_pass = 0; end always @(ConfReg0) begin if (ConfReg0[15]) SYN = 0; else if (~ConfReg0[15]) SYN = 1; end // check when data is generated from model to avoid setuphold check in // those occasion always @(DIn, DOut) begin if (DIn==DOut) deq=1'b1; else deq=1'b0; end assign deg=deq; always @(falling_edge_RESETNeg ) begin: RSTtiming #(200000-1) RST = 0; end always @(rising_edge_RESETNeg) begin disable RSTtiming; #1 RST = 1; end // sequential process for reset control and FSM state transition always @(next_state_event, RST, PoweredUp, RST_out) begin: StateTransition if (PoweredUp) begin if (RESETNeg && RST_out) begin if (next_state_event) current_state = next_state; reseted = 1; end else if (~RESETNeg && falling_edge_RST) begin // no state transition while RESETNeg is low current_state = RESET; RST_in = 1; RST_in <= #1 0; reseted = 0; end end else begin current_state = RESET; reseted = 0; end end //////////////////////////////////////////////////////////////////////////// // Glitch Protection: Inertial Delay does not propagate pulses <2ns //////////////////////////////////////////////////////////////////////////// always @(negedge WENeg_ipd) begin: gWE_n_f #3000 gWE_n = WENeg_ipd; end always @(posedge WENeg_ipd) begin disable gWE_n_f; gWE_n = WENeg_ipd; end always @(negedge CENeg_ipd) begin: gCE_n_f #3000 gCE_n = CENeg_ipd; end always @(posedge CENeg_ipd) begin disable gCE_n_f; gCE_n = CENeg_ipd; end always @(negedge OENeg_ipd) begin: gOE_n_f #3000 gOE_n = OENeg_ipd; end always @(posedge OENeg_ipd) begin disable gOE_n_f; gOE_n = OENeg_ipd; end // Clock active edge -> CLKMerge rising edge, needed for burst sequences always @(rising_edge_CLK) begin: CLKGen if (rising_edge_CLK) begin CLKMerge = 1; #1 CLKMerge = 0; end end always @(rising_edge_START_in) begin : Start_time if (rising_edge_START_in) begin START_out = 0; START_out <= #(tdevice_START) 1; end else START_out = 0; end always @(IACC_in) begin : TIACCB if (~IACC_in) IACC_out = 0; else #(tdevice_IACC) IACC_out = 1; end always @(RST_in) begin : RST_time if (rising_edge_RST_in) begin RST_out = 0; // wait for thold_CENeg_RESETNeg-tRP #(10000000 -200000) RST_out = 1; end end // Address Latch and Bus Cycle Decode always @(falling_edge_gWE_n, falling_edge_gCE_n, falling_edge_AVDNeg, rising_edge_gWE_n , rising_edge_gCE_n, rising_edge_AVDNeg, falling_edge_CENeg, rising_edge_CENeg,Din_event, rising_edge_CLK, A_event, falling_edge_OENeg) begin : BusCycleDecode // Write address latch if (rising_edge_AVDNeg && ~CENeg && OENeg) begin if (WENeg && ~OENeg) UpperAddress = DIn; if (OENeg) WrAddressLatched = {UpperAddress, DIn}; end if (RESETNeg && ((rising_edge_gWE_n && ~gCE_n) || (rising_edge_gCE_n && ~gWE_n) || (rising_edge_gWE_n && rising_edge_gCE_n)) && OENeg) begin // write operation SecAddr = ReturnSectorID(WrAddressLatched); BankID = ReturnBank(WrAddressLatched); Addr = WrAddressLatched; BuffPageAddr = ReturnBuffPage(WrAddressLatched); D_tmp = DIn; WRITE = 0; WRITE <= #1 1; end if (reseted && ConfReg0[15]) begin // Asynchronous Mode address latch if ((falling_edge_AVDNeg || (Din_event && ~AVDNeg)) && WENeg) begin // tACC count AddrRef = ~AddrRef; ADDR_event = $time; end if (rising_edge_AVDNeg && ~CENeg) begin if (WENeg && ~OENeg) UpperAddress = DIn; if (OENeg) AddressLatched = {UpperAddress, DIn}; end if ((falling_edge_OENeg || falling_edge_CENeg) && WENeg && ~CENeg && ~OENeg && AVDNeg) begin // Initiate Read SecAddr = ReturnSectorID(AddressLatched); BankID = ReturnBank(AddressLatched); BuffPageAddr = ReturnBuffPage(AddressLatched); Addr = AddressLatched; READ = 1'b0; #1 READ = 1'b1; end end else if (reseted && ~ConfReg0[15]) begin if (falling_edge_AVDNeg) begin LATCHED = 0; READCYCLE = 0; end // Initiate READ (Burst mode) if (rising_edge_CLK && READCYCLE) begin READCYCLE = 0; IACC_in <= #1 1; BURST = 0; BURST <= #1 1; Check_freq = 1; BurstStarted = 0; end // Synchronous CLK active edge address latch if (rising_edge_CLK && WENeg && ~OENeg && ~CENeg && ~AVDNeg && ~LATCHED) begin UpperAddress = DIn; end if (rising_edge_CLK && WENeg && OENeg && ~CENeg && ~AVDNeg && ~LATCHED) begin READCYCLE = 1; LATCHED = 1; AddressLatched = {UpperAddress, DIn}; SecAddr = ReturnSectorID(AddressLatched); BankID = ReturnBank(AddressLatched); BuffPageAddr = ReturnBuffPage(AddressLatched); Addr = AddressLatched; BurstDelay = 0; IACC_in = 0; IACC_in <= #1 1; AddrRef = ~AddrRef; ADDR_event = $time; BurstStarted = 1; end if ((falling_edge_gWE_n || falling_edge_gCE_n) && ~gCE_n && ~gWE_n && gOE_n) READCYCLE = 0; // Initiate READ, Synchronous mode if (falling_edge_OENeg && WENeg && ~CENeg) begin // Initiate read if (LATCHED) begin SecAddr = ReturnSectorID(AddressLatched); BankID = ReturnBank(AddressLatched); BuffPageAddr = ReturnBuffPage(AddressLatched); Addr = AddressLatched; READ = 0; #1 READ = 1; end end end end event pdone_event, edone_event; // Timing control for the Write Buffer Program Operation // start/ suspend/ resume always @(rising_edge_reseted, rising_edge_PSTART, rising_edge_PSUSP, rising_edge_PRES) begin : ProgTime wrbo = tdevice_WRBO; pow = tdevice_POW; if (rising_edge_reseted) PDONE = 1; // reset done, programing terminated else if (reseted) begin if (rising_edge_PSTART && PDONE) begin if (~( ((~DYB[SA_PGM] ) && ~OTP_ACT && ~LOCK_ACT) || (~DYB[SA_PGM] && OTP_ACT && SA_PGM) || (SA_ERS == SA_PGM && ESP_ACT) || (~LockReg[0] && OTP_ACT && OTP_REG2 && SecAddr == 0 ) || ( OTP_ACT && OTP_REG1 && SecAddr == 0 ) || ( OTP_ACT && SecAddr == 0 && ~(OTP_REG1 || OTP_REG2)) || ~Vpp)) begin start = $time; elapsed = 0; if (progMode == WB) duration = (PCNT + 1) * wrbo; if (progMode == SW) duration = pow; PDONE = 0; -> pdone_event; end else begin PERR = 1'b1; #20000000 PERR = 1'b0; end end else if (rising_edge_PSUSP && ~PDONE) begin elapsed = $time - start; duration = duration - elapsed; disable pdone_process; PDONE = 0; end else if (rising_edge_PRES && ~PDONE) begin start = $time; PDONE = 0; -> pdone_event; end end end always @(pdone_event) begin : pdone_process #(duration) PDONE = 1; end // Timing control for the Erase Operations always @(rising_edge_ESTART, rising_edge_reseted, rising_edge_ESUSP, rising_edge_ERES) begin : ErsTime seo16 = tdevice_SEO16_ts; seo64 = tdevice_SEO64_ts; if (rising_edge_reseted) EDONE = 1; // reset done, ERASE terminated else if (reseted) begin if (rising_edge_ESTART && EDONE) begin cnt16 = 0; cnt64 = 0; if (CHIP_ERS_FLAG) begin for (i=0;i<=SecNum;i=i+1) begin if (DYB[i] == 1'b1 && ~(Vpp == 1'b0) ) begin if ((i<=3 && tmp_char == "1") || (i >= (SecNum -3) && tmp_char == "0")) cnt16 = cnt16 + 1; else cnt64 = cnt64 + 1; end end end else if (SECT_ERS_FLAG) begin if (DYB[SA_ERS] == 1'b1 && ~(Vpp == 1'b0)) begin if ((SA_ERS <=3 && tmp_char == "1") || (SA_ERS >= (SecNum -3) && tmp_char == "0")) cnt16 = cnt16 + 1; else cnt64 = cnt64 + 1; end end if (cnt16 > 0 || cnt64 > 0) begin elapsed = 0; duration = cnt16 * seo16 + cnt64 * seo64; EDONE = 0; -> edone_event; start = $time; end else begin EERR = 1 ; #20000000 EERR = 0; end end else if (rising_edge_ESUSP && ~EDONE) begin elapsed = $time - start; duration = duration - elapsed; disable edone_process; EDONE = 0; end else if (rising_edge_ERES && ~EDONE) begin start = $time; EDONE = 0; -> edone_event; end end end always @(edone_event) begin : edone_process #(duration) EDONE = 1; end // Process that determines clock frequency always @(rising_edge_CLK) begin : CLK_FREQ if (rising_edge_CLK) begin CLK_PER = $time - LAST_CLK; LAST_CLK = $time; #1; if (~ConfReg0[15] && Check_freq) begin if ((CLK_PER < 37037 && WS_Initial < 4) || (CLK_PER < 25000 && WS_Initial < 5) || (CLK_PER < 18518 && WS_Initial < 6) || (CLK_PER < 15151 && WS_Initial < 7) || (CLK_PER < 12500 && WS_Initial < 8) || (CLK_PER < 10526 && WS_Initial < 9)) begin $display ("More wait states are required for"); $display ("this clock frequency value"); end end Check_freq = 0; end end ///////////////////////////////////////////////////////// // Main Behavior Process // combinational process for next state generation ///////////////////////////////////////////////////////// always @(falling_edge_WRITE,reseted,rising_edge_EDONE, rising_edge_START_out,rising_edge_PDONE, CLK, rising_edge_reseted, falling_edge_RST, falling_edge_BURST, falling_edge_PERR, falling_edge_EERR) begin : StateGen if (falling_edge_WRITE ) begin Data = D_tmp; DataLo = D_tmp % 12'h100; AddrCom = Addr % 16'h1000; PATTERN_1 = (AddrCom==16'h555) && (DataLo==8'hAA); PATTERN_2 = (AddrCom==16'h2AA) && (DataLo==8'h55); A_PAT_1 = (AddrCom==16'h555); end if (falling_edge_RST && ~RESETNeg) begin LOCK_ACT = 1'b0; end if (reseted != 1) next_state = current_state; else begin case (current_state) RESET: if (falling_edge_WRITE) begin if (PATTERN_1) next_state = Z001; else if ((AddrCom==8'h55) && (DataLo==8'h98)) next_state = CFI; else next_state = RESET; 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==16'h90)) next_state = AS; else if (A_PAT_1 && (DataLo==16'hA0)) next_state = A0SEEN; else if (AddrCom == 12'h555 && DataLo == 8'hD0) next_state = CR_ENTRY_SET; else if (AddrCom == 12'h555 && DataLo == 8'hC6) next_state = CR_ENTRY_RD; else if (A_PAT_1 && (DataLo==16'h88) && SecAddr == 0) next_state = OTP; else if (A_PAT_1 && (DataLo==16'h40)) begin next_state = LOCKREG_CMDSET; LOCK_ACT = 1'b1; end else if (A_PAT_1 && (DataLo==16'hE0)) next_state = DYB_CMDSET; else if (A_PAT_1 && (DataLo==16'h80)) next_state = C8; else if (DataLo==16'h25) next_state = WR2BUFF_CNT; else next_state = RESET; end end CR_ENTRY_SET: begin if (falling_edge_WRITE) begin if (DataLo == 12'hF0) next_state = RESET; else if (AddrCom == 12'h00) next_state = CR_ENTRY_SET; else next_state <= CR_ENTRY_SET; end end CR_ENTRY_RD: begin if (falling_edge_WRITE) begin if (DataLo == 8'hf0) next_state = RESET; else next_state = CR_ENTRY_RD; end end CFI: begin if (falling_edge_WRITE) begin if (AddrCom == 8'h55 && DataLo == 8'h98) next_state = CFI; else if (DataLo == 8'hF0) next_state = RESET; else next_state = CFI; end end PSP_CFI: begin if (falling_edge_WRITE) begin if (AddrCom == 8'h55 && DataLo == 8'h98) next_state = PSP_CFI; else if (DataLo == 8'hF0) next_state = PSP; else next_state = PSP_CFI; end end ESP_CFI: begin if (falling_edge_WRITE) begin if (AddrCom == 8'h55 && DataLo == 8'h98) next_state = ESP_CFI; else if (DataLo == 8'hF0) next_state = ESP; else next_state = ESP_CFI; end end AS : begin if (falling_edge_WRITE) begin if (DataLo==16'hF0) next_state = RESET; else next_state = AS; end end ESP_AS : begin if (falling_edge_WRITE) begin if (DataLo==16'hF0) next_state = ESP; else next_state = ESP_AS; end end PSP_AS : begin if (falling_edge_WRITE) begin if (DataLo==16'hF0) next_state = PSP; else next_state = PSP_AS; end end LOCKREG_CMDSET : begin if (falling_edge_WRITE) begin if (DataLo == 16'hA0) next_state = LOCKREG_A0SEEN; else if (DataLo == 16'h90) next_state = EXIT_LOCKREG; end end LOCKREG_A0SEEN : begin if (falling_edge_WRITE) begin if (AddrCom == 8'h00) next_state = PGMS; else next_state = LOCKREG_CMDSET; end end EXIT_LOCKREG : begin if (falling_edge_WRITE) begin if (DataLo == 16'h00) begin next_state = RESET; LOCK_ACT = 1'b0; end else next_state = LOCKREG_CMDSET; end end DYB_CMDSET : begin if (falling_edge_WRITE) begin if (DataLo == 16'hA0) next_state = DYB_SETCLEAR; else if (DataLo == 16'h90) next_state = EXIT_DYB; end end DYB_SETCLEAR : begin if (falling_edge_WRITE) next_state = DYB_CMDSET; end EXIT_DYB : begin if (falling_edge_WRITE) begin if (DataLo == 16'h00) begin if (ESP_ACT) next_state = ESP; else if (PSP_ACT) next_state = PSP; else next_state = RESET; end else begin next_state = DYB_CMDSET; end end end A0SEEN : begin if (falling_edge_WRITE) next_state = PGMS; end OTP : begin if (falling_edge_WRITE) begin if (PATTERN_1) next_state = OTP_Z001; else if (DataLo == 16'hA0 && (~PSP_ACT)) next_state = OTP_A0SEEN; else next_state = OTP; end end OTP_Z001 : begin if (falling_edge_WRITE) begin if (PATTERN_2) next_state = OTP_PREL; else next_state = OTP; end end OTP_PREL : begin if (falling_edge_WRITE) begin if (A_PAT_1 && (DataLo == 16'h90)) next_state = OTP_EXIT; else if (A_PAT_1 && DataLo == 16'h25 && (~PSP_ACT) && SecAddr != 0) next_state = WR2BUFF_CNT; else if (A_PAT_1 && (DataLo == 16'hA0) && (~PSP_ACT) && SecAddr != 0) next_state = A0SEEN; else if (A_PAT_1 && (DataLo == 16'h80) && (~PSP_ACT)) next_state = C8; else next_state = OTP; end end OTP_EXIT : begin if (falling_edge_WRITE) begin if (DataLo==16'h00) begin if (PSP_ACT) next_state = PSP; else next_state = RESET; end else next_state = OTP; end end OTP_A0SEEN : begin if (falling_edge_WRITE) if (SecAddr == 0) next_state = PGMS; //set OTP_MEM else next_state = OTP; 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 (A_PAT_1 && DataLo==16'h10 && ~(OTP_ACT)) next_state = ERS; else if (DataLo==16'h30) if (~OTP_ACT || SecAddr != 0) next_state = SERS_EXEC; else next_state = OTP; else next_state = RESET; end end ERS : begin if ((rising_edge_EDONE) || (falling_edge_EERR)) next_state = RESET; end ESPS : begin if (rising_edge_START_out) next_state = ESP; end WR2BUFF_CNT : begin if (falling_edge_WRITE) begin if (SecAddr == SA_PGM && D_tmp <32) next_state = WR2BUFF_LSTA; else next_state = WR2BUFF_ABORT; end end WR2BUFF_LSTA : begin if (falling_edge_WRITE) begin if (SecAddr == SA_PGM ) begin if (LCNT > 0) next_state = WR2BUFF_LOAD; else next_state = WR2BUFF_CONFB; end else next_state = WR2BUFF_ABORT; end end WR2BUFF_LOAD : begin if (falling_edge_WRITE) begin if (WBPage==BuffPageAddr &&((WBSequentialAddr +1) == Addr)) begin if (LCNT>0) next_state = WR2BUFF_LOAD; else next_state = WR2BUFF_CONFB; end else next_state = WR2BUFF_ABORT; end end WR2BUFF_CONFB : begin if (falling_edge_WRITE) if ((SecAddr == SA_PGM) && (DataLo == 16'h29)) next_state = PGMS; else next_state = WR2BUFF_ABORT; end WR2BUFF_ABORT : begin if (falling_edge_WRITE) if (PATTERN_1) next_state = WR2BUFF_Z001; end WR2BUFF_Z001 : begin if (falling_edge_WRITE) if (PATTERN_2) next_state = WR2BUFF_PREL; else next_state = WR2BUFF_ABORT; end WR2BUFF_PREL : begin if (falling_edge_WRITE) begin if (DataLo == 16'hF0) begin if (ESP_ACT) next_state = ESP; else if (OTP_ACT) next_state = OTP; else next_state = RESET; end else next_state = WR2BUFF_ABORT; end end SERS_EXEC : begin if ((rising_edge_EDONE) || (falling_edge_EERR)) begin if (OTP_ACT == 1'b1) next_state = OTP; else next_state = RESET; end else if (EERR != 1'b1) begin if (falling_edge_WRITE) begin if (DataLo==16'hB0 && (BankID == BA_ERS)) next_state = ESPS; end end end ESP : begin if (falling_edge_WRITE) begin if (DataLo==16'h30 && (BankID == BA_ERS)) next_state = SERS_EXEC; else if ((AddrCom == 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) if (DataLo==16'h25 && SecAddr != SA_ERS) //fix SA_PGM next_state = WR2BUFF_CNT; //set ESP else if (A_PAT_1 && DataLo==16'hA0 && SecAddr != SA_ERS) next_state = ESP_A0SEEN; else if (A_PAT_1 && DataLo==16'h90) next_state = ESP_AS; else if (A_PAT_1 && DataLo==16'hE0) next_state = DYB_CMDSET; else next_state = ESP; end ESP_A0SEEN : begin if (falling_edge_WRITE) next_state = PGMS; //set ESP end PGMS : begin if ((rising_edge_PDONE) || (falling_edge_PERR)) begin if (ESP_ACT==1'b1) next_state = ESP; else if (LOCK_ACT==1'b1) next_state = LOCKREG_CMDSET; else if (OTP_ACT==1'b1) next_state = OTP; else next_state = RESET; end else if (falling_edge_WRITE && PERR!=1'b1) begin if (DataLo==16'hB0 && (BankID == BA_PGM)) begin next_state = PSPS; end end end PSPS : begin if (rising_edge_START_out) next_state = PSP; end PSP : begin if (falling_edge_WRITE) begin if (DataLo==16'h30 && (BankID == BA_PGM)) next_state = PGMS; else if (PATTERN_1) next_state = PSP_Z001; else if ((AddrCom==16'h55) && (DataLo==16'h98)) next_state <= PSP_CFI; end end PSP_Z001 : begin if (falling_edge_WRITE) begin if (PATTERN_2) next_state = PSP_PREL; else next_state = PSP; end end PSP_PREL : begin if (falling_edge_WRITE) begin if (A_PAT_1 && DataLo == 16'h88 && SecAddr == 0) next_state = OTP; //set PSP else if (A_PAT_1 && DataLo == 16'h90) next_state = PSP_AS; //set PSP else if (A_PAT_1 && DataLo == 16'hE0) next_state = DYB_CMDSET; //set PSP else next_state = PSP; end end endcase end end ///////////////////////////////////////////////////////////// //Main Behavior Process //combinational process for Read Mode Generation ///////////////////////////////////////////////////////////// always @(falling_edge_RST, falling_edge_BURST, falling_edge_AVDNeg, falling_edge_gWE_n, rising_edge_AVDNeg, rising_edge_gCE_n) begin : ReadModeGen BURST_TR = 0; SYNCREAD = 0; if (falling_edge_RST && ~RESETNeg) RD_MODE = NOSYNC; if (reseted) begin case (current_state) RESET: begin if (falling_edge_BURST) begin BURST_TR = 1; end end AS, ESP_AS, PSP_AS: begin if (falling_edge_BURST) begin if ((BankID == BA_AS && (ReturnAddr(Addr,SecAddr)> 8'hF))|| (PSP_ACT && SecAddr == SA_PGM) || (ESP_ACT && SecAddr == SA_ERS)) SYNCREAD = 1; else BURST_TR = 1; end end LOCKREG_CMDSET: begin if (falling_edge_BURST) begin if (BankID == 0) SYNCREAD = 1; else BURST_TR = 1; end end DYB_CMDSET: begin if (falling_edge_BURST) begin if (BankID == BA_AS || (PSP_ACT && SecAddr == SA_PGM) || (ESP_ACT && SecAddr == SA_ERS)) SYNCREAD = 1; else BURST_TR = 1; end end CFI , ESP_CFI , PSP_CFI : begin if (falling_edge_BURST) if (Addr > 10'h5B || Addr < 10'h10) SYNCREAD = 1; else BURST_TR = 1; end OTP: begin if (falling_edge_BURST) begin if ((SecAddr==0 && Addr > 10'hFF) || (PSP_ACT && SecAddr == SA_PGM) || (ESP_ACT && SecAddr == SA_ERS)) SYNCREAD = 1; else BURST_TR = 1; end end ESPS: begin if (falling_edge_BURST) begin if (BankID == BA_ERS ) SYNCREAD = 1; else BURST_TR = 1; end end SERS_EXEC: begin if (falling_edge_BURST) begin if (BankID == BA_ERS) SYNCREAD = 1; else BURST_TR = 1; end end ESP: begin if (falling_edge_BURST) begin if (SecAddr == SA_ERS) SYNCREAD = 1; else BURST_TR = 1; end end PGMS: begin if (falling_edge_BURST) begin if (BankID == BA_PGM || (SecAddr == SA_ERS && ESP_ACT)) SYNCREAD = 1; else BURST_TR = 1; end end PSPS: begin if (falling_edge_BURST) begin if (BankID == BA_PGM || (SecAddr == SA_ERS && ESP_ACT)) SYNCREAD = 1; else BURST_TR = 1; end end PSP: begin if (falling_edge_BURST) begin if ((SA_PGM == SecAddr) || (ESP_ACT && SA_ERS == SecAddr)) SYNCREAD = 1; else BURST_TR = 1; end end WR2BUFF_ABORT: begin if (falling_edge_BURST) begin if ((BankID == BA_PGM) || (ESP_ACT && SA_ERS == SecAddr)) SYNCREAD = 1; else BURST_TR = 1; end end endcase if ((rising_edge_gCE_n || falling_edge_AVDNeg || falling_edge_gWE_n) && (RD_MODE != NOSYNC)) begin RD_MODE = NOSYNC; end if (BURST_TR) begin if (ConfReg0[2:0] == 3'b000) RD_MODE = CONTINUOUS; else RD_MODE = LINEAR; ReadINIT = 0; ReadINIT <= #1 1; end else if (SYNCREAD) begin RD_MODE = SYNCR; ReadINIT = 0; ReadINIT <= #1 1; end end end /////////////////////////////////////////////////////////////////////// // FSM Output generation and general funcionality /////////////////////////////////////////////////////////////////////// always @(falling_edge_WRITE, rising_edge_EDONE, ER_FLAG, falling_edge_PERR, falling_edge_RST, falling_edge_READ,falling_edge_AVDNeg, rising_edge_CENeg, rising_edge_OENeg, rising_edge_PDONE, rising_edge_START_out, rising_edge_CLKMerge, falling_edge_OENeg, falling_edge_ReadINIT, PERR_EVENT, EERR_EVENT, OENeg) begin : Functional if (falling_edge_WRITE) begin Data = D_tmp; DataLo = D_tmp % 12'h100; AddrCom = Addr % 16'h1000; PATTERN_1 = (AddrCom==16'h555) && (DataLo==8'hAA); PATTERN_2 = (AddrCom==16'h2AA) && (DataLo==8'h55); A_PAT_1 = (AddrCom==16'h555); end oe = falling_edge_READ; if (falling_edge_RST && ~RESETNeg ) begin PSP_ACT = 0; ESP_ACT = 0; OTP_ACT = 0; ConfReg0 = 16'b1010111111001000; START_in = 0; DYB = 0; if (tmp_char=="1") UpperAddress = 16'b0; else UpperAddress = 16'b1; end if (falling_edge_AVDNeg) RDY_temp = 1; if (falling_edge_BURST && FlagBURST) begin FlagBURST = 1'b0; INITIAL = 1; DelayCycSwitch = 0; BurstAddr = Addr; BurstSec = SecAddr; BurstBank = BankID; if (ConfReg0[2:0] == 2) BurstLength = 8; else if (ConfReg0[2:0] == 3) BurstLength = 16; else BurstLength = 0; RDCnt = BurstLength; WS_Initial = 7; if ((ConfReg0[13:11] < 8) && (ConfReg0[13:11] > 0)) WS_Initial = ConfReg0[13:11] +2; BurstDelay = BurstDelay + WS_Initial - 1; // Set WS_Latency according to WS_Initial if (WS_Initial >= 8) WS_Latency = 7; else WS_Latency = WS_Initial - 1; // Set WS_Boundary according to WS_Initial if (WS_Initial == 9) WS_Boundary = 1; else WS_Boundary = 0; IN_W_ELAPSED = 0; DATA_DELAY = 0; BOUNDARY_CROSS = 0; BURST_END = 0; NO_PROGRESS = 0; BusyBound = 0; DelayCyc_CNT = BurstAddr % 8; if (DelayCyc_CNT - (7 - WS_Latency) > 0) DelayCyc_CNT = DelayCyc_CNT - (7 - WS_Latency); else DelayCyc_CNT = 0; if (BurstLength==8 || (BurstLength == 16 && (BurstAddr % 16 >= 8))) DelayCyc_CNT = 0; LatencyAddr = ((BurstAddr/8)*8 + 7); if (current_state == CFI || current_state == PSP_CFI || current_state == ESP_CFI) ReadTarget = CFI_T; else if ((current_state == AS || current_state == PSP_AS || current_state == ESP_AS) && BurstBank == BA_AS) ReadTarget = AS_T; else if (current_state == OTP && BurstSec == 0) ReadTarget = SS_T; else ReadTarget = Mem_T; end if (reseted) begin case (current_state) RESET: begin ESP_ACT = 0; PSP_ACT = 0; OTP_ACT = 0; if (oe && FlagOE) begin FlagOE = 1'b0; READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end Z001: begin end PREL_SETBWB: begin if (falling_edge_WRITE) begin if (A_PAT_1 && (DataLo==16'h90)) begin BA_AS = BankID; end else if (A_PAT_1 && (DataLo==16'h88)) begin OTP_ACT = 1'b1; end else if (DataLo==16'h25) begin SA_PGM = SecAddr; BA_PGM = BankID; progMode = WB; end else if (A_PAT_1 && (DataLo==16'hE0)) begin BA_DYB = BankID; end end end CR_ENTRY_SET: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h00) begin ConfReg0 = Data; end end end CR_ENTRY_RD: begin if (oe && FlagOE) begin FlagOE = 1'b0; if (Addr % 16'h100 == 0) DOut_zd = ConfReg0; else DOut_zd = UNDEFINED; end end CFI, PSP_CFI , ESP_CFI: begin if (oe && FlagOE) begin FlagOE = 1'b0; if (Addr >= 16'h10 && Addr <= 16'h5B) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,CFI_T); DOut_zd = OutputD; end else DOut_zd = UNDEFINED; $display(" Invalid CFI query address "); end end AS, PSP_AS , ESP_AS: begin if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_AS) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,AS_T); DOut_zd = OutputD; end else begin if (ESP_ACT && SecAddr == SA_ERS) begin Status[7] = 1; // Status(6) No toggle Status[5] = 0; Status[2] = ~ Status[2]; // toggle DOut_zd = Status; end else if (PSP_ACT && SecAddr == SA_PGM) DOut_zd = UNDEFINED; else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end end LOCKREG_CMDSET: begin if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == 0) begin if (Addr % 16'h100 == 0) DOut_zd = LockReg; else DOut_zd = UNDEFINED; end else if (BankID != 0) begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end LOCKREG_A0SEEN : begin if (falling_edge_WRITE) begin if (AddrCom==16'h00) begin tempLo = Data; PSTART = 1'b1; PSTART <= #1 1'b0; PSUSP = 1'b0; PRES = 1'b0; PCNT = 32; WBData[0] = -1; if (~Viol) begin WBData[0] = tempLo; end progMode = SW; WBAddr[0] = 0;//Addr don't care XXX WBPage = BuffPageAddr; PGMS_FLAG = LREG; PR_FLAG = 1'b0; SA_PGM = SecAddr; BA_PGM = BankID; temp = DataLo; Status[7] = ~temp[7]; //default state DYBs after lock register programmed DYB = 0; end end end EXIT_LOCKREG: begin end DYB_CMDSET: begin if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_DYB) begin DOut_zd[15:1] = 15'b0; DOut_zd[0] = DYB[SecAddr]; end else begin if (ESP_ACT && SecAddr == SA_ERS) begin Status[7] = 1; // Status(6) No toggle Status[5] = 0; Status[2] = ~ Status[2]; // toggle DOut_zd = Status; end else if (PSP_ACT && SecAddr == SA_PGM) DOut_zd = UNDEFINED; else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end end DYB_SETCLEAR : begin if (falling_edge_WRITE) begin if (BankID == BA_DYB) begin if ( DataLo == 16'h00 && (~ESP_ACT || SecAddr != SA_ERS) && (~PSP_ACT || SecAddr != SA_PGM)) DYB[SecAddr] = 1'b0; else if ( DataLo == 16'h01 && (~ESP_ACT || SecAddr != SA_ERS) && (~PSP_ACT || SecAddr != SA_PGM)) DYB[SecAddr] = 1'b1; end end end EXIT_DYB: begin end A0SEEN : begin if (falling_edge_WRITE) begin PSTART = 1'b1; PSTART <= #1 1'b0; PSUSP = 1'b0; PRES = 1'b0; PCNT = 32; PGMS_FLAG = MEMORY; PR_FLAG = 1'b0; progMode = SW; WBData[0] = -1; if (~Viol) WBData[0] = Data; WBAddr[0] = Addr; WBPage = BuffPageAddr; SA_PGM = SecAddr; BA_PGM = BankID; temp = DataLo; Status[7] = ~temp[7]; end end OTP : begin if (oe && FlagOE) begin FlagOE = 1'b0; //read SecSi Sector Region if (SecAddr == 0) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); DOut_zd = OutputD; end else begin if (ESP_ACT && SecAddr == SA_ERS) begin Status[7] = 1; // Status(6) No toggle Status[5] = 0; Status[2] = ~ Status[2]; // toggle DOut_zd = Status; end else if (PSP_ACT && SecAddr == SA_PGM) DOut_zd = UNDEFINED; else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end end OTP_Z001 : begin end OTP_PREL : begin if (falling_edge_WRITE) begin if (A_PAT_1 && DataLo == 16'hA0 && ~PSP_ACT && SecAddr != 0 ) begin progMode = SW; //fix Sector Address SA_PGM SA_PGM = SecAddr; BA_PGM = BankID; //activate OTP_MEM OTP_ACT = 1'b1; end else if (A_PAT_1 && DataLo == 16'h25 && ~PSP_ACT && SecAddr != 0 ) begin progMode = WB; //fix Sector Address SA_PGM SA_PGM = SecAddr; BA_PGM = BankID; //activate OTP_MEM OTP_ACT = 1'b1; end end end OTP_EXIT : begin end OTP_A0SEEN : begin if (falling_edge_WRITE) begin if (SecAddr == 0) begin OTP_ACT = 1'b1; //////////////////////////////////////////////////////// //SecSi programming: TBD //////////////////////////////////////////////////////// PSTART = 1'b1; PSTART <= #1 1'b0; PSUSP = 1'b0; PRES = 1'b0; PCNT = 32; progMode = SW; //fix Sector Address SA_PGM SA_PGM = SecAddr; BA_PGM = BankID; WBData[0] = -1; PGMS_FLAG = OTP_MEM; PR_FLAG = 1'b0; if (~Viol) begin WBData[0] = Data; end WBAddr[0] = Addr; WBPage = BuffPageAddr; if (ReturnAddr(WBAddr[0],SecAddr)>= 0 && ReturnAddr(WBAddr[0],SecAddr)<= 16'h7F) OTP_REG1 = 1'b1; else if (ReturnAddr(WBAddr[0],SecAddr)> 16'h7F && ReturnAddr(WBAddr[0],SecAddr)<= 16'hFF) OTP_REG2 = 1'b1; if (ReturnAddr(Addr, SecAddr) >= 256) begin $display("Invalid program address in SecSi region"); $display("Address= %d", ReturnAddr(Addr,SecAddr)); end if (OTP_REG1) begin $display("Invalid program address in SecSi region"); $display("Factory Address= %d", ReturnAddr(Addr,SecAddr)); end temp = DataLo; Status[7] = ~temp[7]; end else $display("Invalid sector Address in SecSi"); end end C8 : begin end C8_Z001 : begin end C8_PREL : begin if (falling_edge_WRITE) begin if ((A_PAT_1) && (DataLo==16'h10)) begin //Start Chip Erase CHIP_ERS_FLAG = 1'b1; SECT_ERS_FLAG = 1'b0; ESTART = 1'b1; ESTART <= #1 1'b0; ESUSP = 1'b0; ERES = 1'b0; Status = 16'b0000000000000000; ER_FLAG = 1'b0; end else if (DataLo==16'h30) begin if (~OTP_ACT || SecAddr != 0) begin //put selected sector to sec. ers. queue //start timeout CHIP_ERS_FLAG = 1'b0; SECT_ERS_FLAG = 1'b1; SA_ERS = SecAddr; BA_ERS = BankID; START_in = 1'b0; ESTART = 1'b1; ESTART <= #1 1'b0; ESUSP = 1'b0; ERES = 1'b0; ER_FLAG = 1'b0; end end end end ERS : begin if (EERR != 1) begin if (~ER_FLAG) begin ER_FLAG = 1; for (i=0; i<= SecNum; i=i+1) begin if (DYB[i] && Vpp) begin if (i <= 3 && (tmp_char=="1")) begin for (j=i*(SecSize16+1)+sgsaB[0]; j<=i*(SecSize16+1)+sgsaB[0]+SecSize16; j=j+1) Mem[j] = -1; end else if (tmp_char == "1") begin for (j=(i-4)*(SecSize64+1)+sgsaB[1]; j<= (i-4)*(SecSize64+1)+sgsaB[1]+SecSize64; j=j+1) Mem[j] = -1; end else if (i < (SecNum-3) && (tmp_char == "0")) begin for (j=i*(SecSize64+1)+sgsaT[0]; j<= i*(SecSize64+1)+sgsaT[0]+SecSize64; j=j+1) Mem[j] = -1; end else begin for (j=(i-(SecNum-3))*(SecSize16+1) +sgsaT[1]; j<= (i-(SecNum-3))*(SecSize16+1)+sgsaT[1]+ +SecSize16; j=j+1) Mem[j] = -1; end end end end if (EDONE) begin ER_FLAG = 0; for (i=0; i<= SecNum; i=i+1) begin if (DYB[i] && Vpp) begin if (i <= 3 && (tmp_char=="1")) begin for (j=i*(SecSize16+1)+sgsaB[0]; j<=i*(SecSize16+1)+sgsaB[0]+SecSize16; j=j+1) Mem[j] = MaxData; end else if (tmp_char == "1") begin for (j=(i-4)*(SecSize64+1)+sgsaB[1]; j<= (i-4)*(SecSize64+1)+sgsaB[1]+SecSize64; j=j+1) Mem[j] = MaxData; end else if (i < (SecNum-3) && (tmp_char == "0")) begin for (j=i*(SecSize64+1)+sgsaT[0]; j<= i*(SecSize64+1)+sgsaT[0]+SecSize64; j=j+1) Mem[j] = MaxData; end else begin for (j=(i-(SecNum-3))*(SecSize16+1)+ sgsaT[1]; j<= (i-(SecNum-3))*(SecSize16+1)+sgsaT[1]+ SecSize16; j=j+1) Mem[j] = MaxData; end end end end end if (oe && FlagOE) begin FlagOE = 1'b0; /////////////////////////////////////////////////////////// //read status Erase Busy /////////////////////////////////////////////////////////// Status[7] = 1'b0; Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[3] = 1'b1; Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status[15:0]; end end ESPS : begin if (START_out == 1) begin ESP_ACT = 1'b1; START_in = 1'b0; end else if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_ERS) begin Status[7] = 1'b0; Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[3] = 1'b1; if (SA_ERS == SecAddr ) Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status[15:0]; end else if (BankID != BA_ERS) begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end WR2BUFF_CNT : begin if (falling_edge_WRITE) begin if ((SecAddr == SA_PGM) &&(D_tmp < 32)) begin cnt = D_tmp; PCNT = cnt; LCNT = cnt; end end end WR2BUFF_LSTA : begin if (falling_edge_WRITE) begin if(SecAddr == SA_PGM) // fix WBPage begin WBData[cnt] = -1; if (~Viol) WBData[cnt] = Data; WBAddr[cnt] = Addr; if (cnt>0) cnt = cnt -1; //save last loaded data for data polling temp = DataLo; Status[7] = ~temp[7]; WBPage = BuffPageAddr; WBSequentialAddr = Addr; // fix WBSequentialAddrr end LCNT = cnt; end end WR2BUFF_LOAD : begin if (falling_edge_WRITE) begin if (BuffPageAddr == WBPage) begin WBData[cnt] = -1; if (~Viol) WBData[cnt] = Data; WBAddr[cnt] = Addr; if (cnt>0) cnt = cnt -1; //save last loaded data for data polling temp = DataLo; Status[7] = ~temp[7]; WBSequentialAddr = Addr; // fix WBSequentialAddrr end LCNT = cnt; end end WR2BUFF_CONFB: begin if (falling_edge_WRITE) begin if ((SecAddr == SA_PGM) && (DataLo == 16'h29)) begin PSTART = 1'b1; PSTART <= #1 1'b0; PSUSP = 1'b0; PRES = 1'b0; PR_FLAG = 1'b0; PGMS_FLAG = MEMORY; end end end WR2BUFF_ABORT : begin if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_PGM ) begin /////////////////////////////////////////////////////// //read status / write buffer abort /////////////////////////////////////////////////////// Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[1] = 1'b1; DOut_zd[15:0] = Status; end else if (SecAddr == SA_ERS && ESP_ACT ) begin /////////////////////////////////////////////////////// //read status / write buffer abort /////////////////////////////////////////////////////// Status[7] = 1'b1; //Status[6] no toggle Status[5] = 1'b0; Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status; end else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end WR2BUFF_Z001 : begin end WR2BUFF_PREL : begin if (falling_edge_WRITE) begin if (DataLo == 16'hF0) begin PSP_ACT = 1'b0; end end end SERS_EXEC: begin if (EERR != 1) begin if (~ER_FLAG) begin ER_FLAG = 1; if (DYB[SA_ERS] && Vpp) begin if (SA_ERS <= 3 && (tmp_char=="1")) begin for (j=SA_ERS*(SecSize16+1)+sgsaB[0]; j<=SA_ERS*(SecSize16+1)+sgsaB[0]+SecSize16; j=j+1) Mem[j] = -1; end else if (tmp_char == "1") begin for (j=(SA_ERS-4)*(SecSize64+1)+sgsaB[1]; j<= (SA_ERS-4)*(SecSize64+1)+sgsaB[1]+SecSize64; j=j+1) Mem[j] = -1; end else if (SA_ERS < (SecNum-3) && (tmp_char == "0")) begin for (j=SA_ERS*(SecSize64+1)+sgsaT[0]; j<= SA_ERS*(SecSize64+1)+sgsaT[0]+SecSize64; j=j+1) Mem[j] = -1; end else begin for (j=(SA_ERS-(SecNum-3))*(SecSize16+1) +sgsaT[1]; j<= (SA_ERS-(SecNum-3))*(SecSize16+1)+sgsaT[1]+ +SecSize16; j=j+1) Mem[j] = -1; end end end if (EDONE) begin ER_FLAG = 0; if (DYB[SA_ERS] && Vpp) begin if (SA_ERS <= 3 && (tmp_char=="1")) begin for (j=SA_ERS*(SecSize16+1)+sgsaB[0]; j<=SA_ERS*(SecSize16+1)+sgsaB[0]+SecSize16; j=j+1) Mem[j] = MaxData; end else if (tmp_char == "1") begin for (j=(SA_ERS-4)*(SecSize64+1)+sgsaB[1]; j<= (SA_ERS-4)*(SecSize64+1)+sgsaB[1]+SecSize64; j=j+1) Mem[j] = MaxData; end else if (SA_ERS < (SecNum-3) && (tmp_char == "0")) begin for (j=SA_ERS*(SecSize64+1)+sgsaT[0]; j<= SA_ERS*(SecSize64+1)+sgsaT[0]+SecSize64; j=j+1) Mem[j] = MaxData; end else begin for (j=(SA_ERS-(SecNum-3))*(SecSize16+1)+ sgsaT[1]; j<= (SA_ERS-(SecNum-3))*(SecSize16+1)+sgsaT[1]+ SecSize16; j=j+1) Mem[j] = MaxData; end end end else if (falling_edge_WRITE) begin if (DataLo==16'hB0 && (BankID == BA_ERS)) begin START_in = 1'b1; ESUSP = 1; ESUSP <= #1 0; end end end if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_ERS) begin Status[7] = 1'b0; Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; Status[3] = 1'b1; if (SA_ERS == SecAddr ) Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status[15:0]; end else if (BankID != BA_ERS) begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end ESP : begin ESUSP = 1'b0; if (falling_edge_WRITE) begin if (DataLo == 16'h30 && (BankID == BA_ERS)) begin //resume erase ERES = 1'b1; ERES <= #1 1'b0; ESP_ACT = 1'b0; end end //ready signal active else if (oe && FlagOE) begin FlagOE = 1'b0; /////////////////////////////////////////////////////////// //read /////////////////////////////////////////////////////////// if (SA_ERS != SecAddr) begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end else begin Status[7] = 1'b1; //Status[6] no toggle Status[5] = 1'b0; Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status; end end end ESP_Z001 : begin end ESP_PREL : begin if (falling_edge_WRITE) begin if (DataLo == 16'h25 && ~PSP_ACT) begin progMode = WB; //fix SA_PGM SA_PGM = SecAddr; BA_PGM = BankID; ESP_ACT = 1'b1; end else if (A_PAT_1 && (DataLo == 16'h90)) begin BA_AS = BankID; ESP_ACT = 1'b1; end else if (A_PAT_1 && (DataLo == 16'hE0)) begin BA_DYB = BankID; ESP_ACT = 1'b1; end end end ESP_A0SEEN : begin if (falling_edge_WRITE) begin ESP_ACT = 1'b1; PSTART = 1'b1; PSTART <= #1 1'b0; PRES = 1'b0; PSUSP = 1'b0; PCNT = 32; WBData[0] = -1; if (~Viol) begin WBData[0] = Data; end WBAddr[0] = Addr; WBPage = BuffPageAddr; SA_PGM = SecAddr; BA_PGM = BankID; PGMS_FLAG = MEMORY; PR_FLAG = 1'b0; progMode = SW; temp = DataLo; Status[7] = ~temp[7]; end end PGMS : begin if ((PERR != 1'b1) && ~(falling_edge_PERR)) begin if (PR_FLAG == 1'b0) begin PR_FLAG = 1'b1; if (PCNT < 32) //buffer begin wr_cnt = PCNT; end else //Word/Byte program wr_cnt = 0; for (i=wr_cnt;i>=0;i=i-1) begin new_int= WBData[i]; if (WBAddr[i] < 0) old_int= -1; else if (PGMS_FLAG == MEMORY) old_int=Mem[WBAddr[i]]; else if (PGMS_FLAG == OTP_MEM) old_int=SecSiMem[ReturnAddr(WBAddr[i],0)]; else if (PGMS_FLAG == LREG) old_bit=LockReg[15:0]; if (new_int>-1) begin new_bit = new_int; if ((PGMS_FLAG == LREG) && (old_bit[0]!==1'bx)) begin if (old_bit[0]==1'b0) new_bit[0] = 1'b0; end else begin if ((old_int>-1) && ((PGMS_FLAG == OTP_MEM) || (PGMS_FLAG == MEMORY)) ) begin old_bit = old_int; for(j=0;j<=15;j=j+1) begin if (~old_bit[j]) new_bit[j]=1'b0; end end else new_bit[0] = 1'bx; end if (new_bit[0] !==1'bx) begin new_int=new_bit; WBData[i]= new_int; end else WBData[i]= -1; end else WBData[i]= -1; end for (i=wr_cnt;i>=0;i=i-1) begin if (PGMS_FLAG == MEMORY) begin if (progMode == WB) Mem[WBAddr[i]] = -1; if (progMode == SW) Mem[WBAddr[i]] = -1; end else if (PGMS_FLAG == OTP_MEM) SecSiMem[ReturnAddr(WBAddr[i],0)] = -1; else if ( PGMS_FLAG == LREG ) LockReg[15:0] = 16'bx; end end if (PDONE && ~PERR_EVENT) begin PR_FLAG = 1'b0; for (i=wr_cnt;i>=0;i=i-1) begin if ((WBAddr[i]> -1) && (WBData[i] > -1)) begin if (PGMS_FLAG == MEMORY) Mem[WBAddr[i]] = WBData[i]; else if (PGMS_FLAG == OTP_MEM) SecSiMem[ReturnAddr(WBAddr[i],0)]= WBData[i]; else if ( PGMS_FLAG == LREG ) LockReg[15:0] = WBData[i]; end WBData[i]= -1; end end if (falling_edge_WRITE) begin if (DataLo == 16'hB0 && (BankID == BA_PGM)) begin START_in = 1'b1; end end end if ((rising_edge_PDONE )||(falling_edge_PERR)) begin OTP_REG1 = 1'b0; OTP_REG2 = 1'b0; end if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_PGM) begin /////////////////////////////////////////// //read status /////////////////////////////////////////// Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; //Status[2] no toggle Status[1] = 1'b0; DOut_zd[15:0] = Status[15:0]; end else if (SecAddr == SA_ERS && ESP_ACT ) begin Status[7] = 1'b1; //Status[6] no toggle Status[5] = 1'b0; Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status; end else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end PSPS: begin PSUSP = 1'b1; if (START_out == 1'b1) begin START_in = 1'b0; end else if (oe && FlagOE) begin FlagOE = 1'b0; if (BankID == BA_PGM) begin //////////////////////////////////////////////////////// //read status / stil programming //////////////////////////////////////////////////////// Status[6] = ~Status[6]; //toggle Status[5] = 1'b0; //Status[2) no toggle Status[1] = 1'b0; DOut_zd[15:0] = Status; end else if (SecAddr == SA_ERS && ESP_ACT) begin Status[7] = 1'b1; //Status[6] no toggle Status[5] = 1'b0; Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status; end else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end PSP: begin PSUSP<= 1'b0; if (falling_edge_WRITE) begin if (DataLo == 16'h30 && (BankID == BA_PGM)) begin PRES = 1'b1; PRES <= #1 1'b0; PSP_ACT = 1'b0; end end else if (oe && FlagOE) begin FlagOE = 1'b0; /////////////////////////////////////////////////////////// //read - program suspend /////////////////////////////////////////////////////////// if (SecAddr == SA_PGM) //read program suspended page DOut_zd = UNDEFINED; else if (ESP_ACT && SA_ERS==SecAddr) begin Status[7] = 1'b1; // Status[6) No toggle Status[5] = 1'b0; Status[2] = ~Status[2]; //toggle DOut_zd[15:0] = Status; end else begin READMEM(Addr,SecAddr,Mem_T); DOut_zd = OutputD; end end end PSP_Z001 : begin end PSP_PREL : begin if (falling_edge_WRITE) begin if (A_PAT_1 && (DataLo==16'h88) && SecAddr == 0) PSP_ACT = 1'b1; else if (A_PAT_1 && (DataLo==16'h90)) begin BA_AS = BankID; PSP_ACT = 1'b1; end else if (A_PAT_1 && (DataLo==16'hE0)) begin BA_DYB = BankID; PSP_ACT = 1'b1; end end end endcase end // Burst functionality case (RD_MODE) LINEAR: begin // linear mode only implemented if (rising_edge_CLKMerge || falling_edge_ReadINIT) begin if (BurstDelay > 0 ) begin BurstDelay = BurstDelay - 1; if (~OENeg) RDY_temp = 0; if (BurstDelay == 1) begin if (~ConfReg0[8]) begin RDY_temp = 1; BurstStarted = 1; end end if (BurstDelay == 0) begin RDY_temp = 1; BurstStarted = 1; end end if (BurstDelay == 0) begin if (IACC_out == 1 || ~IN_W_ELAPSED) begin if (BURST_END) RDY_temp = 0; else if (INITIAL) begin if (DelayCycSwitch == 0 && BurstAddr != LatencyAddr) begin RDY_temp = 1; READ_BURST_DATA(BurstAddr, BurstSec, ReadTarget); NEXT_ADDR_LIN(BurstAddr, BurstLength); CHECK_END(RDCnt, BURST_END); if (BurstAddr == LatencyAddr) begin if (DelayCyc_CNT == 0) DelayCycSwitch = 4; else DelayCycSwitch = 1; end end else if (DelayCycSwitch==0 && BurstAddr == LatencyAddr) begin if (DelayCyc_CNT >0) RDY_temp = ConfReg0[8]; else RDY_temp =1; READ_BURST_DATA(BurstAddr, BurstSec, ReadTarget); if (DelayCyc_CNT == 0) begin INITIAL = 0; NEXT_ADDR_LIN(BurstAddr, BurstLength); CHECK_END(RDCnt,BURST_END); DelayCycSwitch = 0; end else begin DelayCyc_CNT = DelayCyc_CNT - 1; if (DelayCyc_CNT == 0) DelayCycSwitch = 3; else DelayCycSwitch = 2; end end else if (DelayCycSwitch == 1) begin RDY_temp = ConfReg0[8]; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); DelayCyc_CNT = DelayCyc_CNT - 1; if (DelayCyc_CNT ==0) DelayCycSwitch = 3; else DelayCycSwitch = 2; end else if (DelayCycSwitch == 2) begin RDY_temp = 0; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); DelayCyc_CNT = DelayCyc_CNT - 1; if (DelayCyc_CNT ==0) DelayCycSwitch = 3; end else if (DelayCycSwitch == 3) begin READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); NEXT_ADDR_LIN(BurstAddr, BurstLength); CHECK_END(RDCnt, BURST_END); RDY_temp = ~ConfReg0[8]; DelayCycSwitch = 4; end else // DelayCycSwitch = 4 begin INITIAL = 0; DelayCycSwitch = 0; RDY_temp = 1; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); NEXT_ADDR_LIN(BurstAddr, BurstLength); CHECK_END(RDCnt, BURST_END); end if (BURST_END) RDY_temp = ConfReg0[8]; end else begin READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); NEXT_ADDR_LIN(BurstAddr, BurstLength); CHECK_END(RDCnt, BURST_END); if (~BURST_END) RDY_temp = 1; else RDY_temp = ConfReg0[8]; end end else begin if (~OENeg) $display("More wait states should be programmed"); end if (IN_W_ELAPSED) begin DATA_DELAY = 1; end IN_W_ELAPSED = 1; end end end CONTINUOUS: begin // continuous mode if (rising_edge_CLKMerge || falling_edge_ReadINIT) begin if (BurstDelay > 0) begin BurstDelay = BurstDelay - 1; if (~OENeg) RDY_temp = 0; if (BurstDelay == 1) begin if (ConfReg0[8] == 0) begin RDY_temp = 1; BurstStarted = 1; end end if (BurstDelay == 0) begin RDY_temp = 1; BurstStarted = 1; end end if (BurstDelay == 0) begin if (IACC_out == 1 || ~IN_W_ELAPSED) begin if (INITIAL) begin if (DelayCycSwitch == 0 && BurstAddr != LatencyAddr) begin RDY_temp = 1; READ_BURST_DATA(BurstAddr, BurstSec, ReadTarget); NEXT_ADDR(BurstAddr, BurstSec, ReadTarget); if (BurstAddr == LatencyAddr) begin if (DelayCyc_CNT == 0) DelayCycSwitch = 4; else DelayCycSwitch = 1; end end else if (DelayCycSwitch == 0 && BurstAddr == LatencyAddr) begin RDY_temp = ConfReg0[8]; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); DelayCyc_CNT = DelayCyc_CNT - 1; if (DelayCyc_CNT == 0) DelayCycSwitch = 3; else DelayCycSwitch = 2; end else if (DelayCycSwitch == 1) begin RDY_temp = ConfReg0[8]; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); DelayCyc_CNT = DelayCyc_CNT - 1; if (DelayCyc_CNT == 0) DelayCycSwitch = 3; else DelayCycSwitch = 2; end else if (DelayCycSwitch == 2) begin RDY_temp = 0; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); DelayCyc_CNT = DelayCyc_CNT - 1; if (DelayCyc_CNT == 0) DelayCycSwitch = 3; end else if (DelayCycSwitch == 3) begin READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); if (BurstAddr % 16'h80 == 16'h7F) begin if (WS_Boundary > 0) RDY_temp = 0; else begin if (ReadTarget == Mem_T) CheckBoundary(BusyBound, BurstAddr); NEXT_ADDR(BurstAddr,BurstSec, ReadTarget); if (BusyBound) RDY_temp = 0; else RDY_temp = ~ConfReg0[8]; end INITIAL = 0; BOUNDARY_CROSS = 1; BoundarySwitch = 0; end else begin NEXT_ADDR(BurstAddr, BurstSec, ReadTarget); RDY_temp = ~ConfReg0[8]; DelayCycSwitch = 4; end end else // DelayCycSwitch = 4 begin INITIAL = 0; DelayCycSwitch = 0; READ_BURST_DATA(BurstAddr,BurstSec,ReadTarget); if (BurstAddr % 16'h80 == 16'h7F) begin if (WS_Boundary > 0) RDY_temp = ConfReg0[8]; else begin if (ReadTarget == Mem_T) CheckBoundary(BusyBound,BurstAddr); NEXT_ADDR(BurstAddr, BurstSec, ReadTarget); RDY_temp = 1; end BOUNDARY_CROSS = 1; BoundarySwitch = 0; end else begin RDY_temp = 1; NEXT_ADDR(BurstAddr, BurstSec, ReadTarget); end end end else if (BOUNDARY_CROSS) begin if (BoundarySwitch == 0) begin if (WS_Boundary > 0) begin READ_BURST_DATA(BurstAddr, BurstSec, ReadTarget); WS_Boundary = WS_Boundary - 1; if (ReadTarget == Mem_T) CheckBoundary(BusyBound, BurstAddr); if (BusyBound) RDY_temp = 0; else RDY_temp = ~ConfReg0[8]; NEXT_ADDR(BurstAddr, BurstSec, ReadTarget); BoundarySwitch = 2; end else BoundarySwitch = 3; end else BoundarySwitch = 3; if (BoundarySwitch == 3) begin if (BusyBound) begin NO_PROGRESS = 1; DOut_burst = 16'b0; RDY_temp = 0; end else begin RDY_temp = 1; READ_BURST_DATA(BurstAddr, BurstSec, ReadTarget); NEXT_ADDR(BurstAddr, BurstSec,ReadTarget); end BOUNDARY_CROSS = 0; end end else if (NO_PROGRESS) RDY_temp = 0; else begin READ_BURST_DATA(BurstAddr, BurstSec,ReadTarget); if (BurstAddr % 16'h80 == 16'h7F) begin if (WS_Boundary > 0) RDY_temp = ConfReg0[8]; else begin if (ReadTarget == Mem_T) CheckBoundary(BusyBound,BurstAddr); NEXT_ADDR(BurstAddr,BurstSec,ReadTarget); RDY_temp = 1; end BOUNDARY_CROSS = 1; BoundarySwitch = 0; end else begin NEXT_ADDR(BurstAddr,BurstSec,ReadTarget); RDY_temp = 1; end end end else begin if (~OENeg) $display("More wait states should be programmed"); end if (IN_W_ELAPSED) DATA_DELAY = 1; IN_W_ELAPSED = 1; end end end SYNCR: begin if (rising_edge_CLKMerge) begin if (BurstDelay > 0) begin BurstDelay = BurstDelay - 1; if (~OENeg) RDY_temp = 0; if (BurstDelay == 1) begin if (ConfReg0[8] == 0) begin RDY_temp = 1; BurstStarted = 1; end end end if (BurstDelay == 0) begin RDY_temp = 1; BurstStarted = 1; end end end NOSYNC: begin end endcase if (RD_MODE != NOSYNC && IN_W_ELAPSED && ~OENeg) DOut_zd = DOut_burst; if (falling_edge_OENeg && ~BurstStarted) RDY_temp = 0; if (rising_edge_CENeg) RDY_temp = 1; // Output Disable Control if (rising_edge_CENeg || OENeg || (~RST && ~RESETNeg) || (rising_edge_OENeg) && (RD_MODE == NOSYNC || RD_MODE == SYNCR || INITIAL)) DOut_zd = 16'bz; end ////////////////////////////////////////////////////////////////// // CFI Preload Process ////////////////////////////////////////////////////////////////// initial begin : CFIPreload for (i=16; i<= 103; i=i+1) CFIMem[i] = 0; // CFI Query Identification String CFIMem[16] = 16'h0051; CFIMem[17] = 16'h0052; CFIMem[18] = 16'h0059; CFIMem[19] = 16'h0002; CFIMem[20] = 16'h0000; CFIMem[21] = 16'h0040; CFIMem[22] = 16'h0000; CFIMem[23] = 16'h0000; CFIMem[24] = 16'h0000; CFIMem[25] = 16'h0000; CFIMem[26] = 16'h0000; // System Interface String CFIMem[27] = 16'h0017; CFIMem[28] = 16'h0019; CFIMem[29] = 16'h0000; CFIMem[30] = 16'h0000; CFIMem[31] = 16'h0008; CFIMem[32] = 16'h0009; CFIMem[33] = 16'h000A; CFIMem[34] = 16'h0011; CFIMem[35] = 16'h0003; CFIMem[36] = 16'h0003; CFIMem[37] = 16'h0003; CFIMem[38] = 16'h0003; // Device Geometry Definition CFIMem[39] = 16'h0017; CFIMem[40] = 16'h0001; CFIMem[41] = 16'h0000; CFIMem[42] = 16'h0006; CFIMem[43] = 16'h0000; CFIMem[44] = 16'h0002; if (tmp_char == "0") CFIMem[45] = 16'h007E; else if (tmp_char == "1") CFIMem[45] = 16'h0003; if (tmp_char == "0") CFIMem[46] = 16'h0070; else if (tmp_char == "1") CFIMem[46] = 16'h0000; if (tmp_char == "0") CFIMem[47] = 16'h0000; else if (tmp_char == "1") CFIMem[47] = 16'h0040; if (tmp_char == "0") CFIMem[48] = 16'h0001; else if (tmp_char == "1") CFIMem[48] = 16'h0000; if (tmp_char == "0") CFIMem[49] = 16'h0003; else if (tmp_char == "1") CFIMem[49] = 16'h007E; if (tmp_char == "0") CFIMem[50] = 16'h0000; else if (tmp_char == "1") CFIMem[50] = 16'h0070; if (tmp_char == "0") CFIMem[51] = 16'h0040; else if (tmp_char == "1") CFIMem[51] = 16'h0000; if (tmp_char == "0") CFIMem[52] = 16'h0000; else if (tmp_char == "1") CFIMem[52] = 16'h0001; CFIMem[53] = 16'h00FF; CFIMem[54] = 16'h00FF; CFIMem[55] = 16'h00FF; CFIMem[56] = 16'h00FF; CFIMem[57] = 16'h00FF; CFIMem[58] = 16'h00FF; CFIMem[59] = 16'h00FF; CFIMem[60] = 16'h00FF; // Primary Algorithm-Specific Extended Query CFIMem[64] = 16'h0050; CFIMem[65] = 16'h0052; CFIMem[66] = 16'h0049; CFIMem[67] = 16'h0031; CFIMem[68] = 16'h0034; CFIMem[69] = 16'h0020; CFIMem[70] = 16'h0002; CFIMem[71] = 16'h0001; CFIMem[72] = 16'h0000; CFIMem[73] = 16'h0008; CFIMem[74] = 16'h0020; CFIMem[75] = 16'h0001; CFIMem[76] = 16'h0000; CFIMem[77] = 16'h0085; CFIMem[78] = 16'h0095; if (tmp_char == "0") CFIMem[79] = 16'h0003; else if (tmp_char == "1") CFIMem[79] = 16'h0002; CFIMem[80] = 16'h0001; CFIMem[81] = 16'h0000; CFIMem[82] = 16'h0008; CFIMem[83] = 16'h000E; CFIMem[84] = 16'h000E; CFIMem[85] = 16'h0005; CFIMem[86] = 16'h0005; CFIMem[87] = 16'h0004; if (tmp_char == "0") CFIMem[88] = 16'h0020; else if (tmp_char == "1") CFIMem[88] = 16'h0023; CFIMem[89] = 16'h0020; CFIMem[90] = 16'h0020; if (tmp_char == "0") CFIMem[91] = 16'h0023; else if (tmp_char == "1") CFIMem[91] = 16'h0020; end task READMEM; input integer Address; input integer SecAddr; input reg[8:0] Targ; reg [15:0] ReadData; begin case (Targ) Mem_T : begin if (Mem[Address] != -1) ReadData = Mem[Address]; else ReadData = 16'bx; end SS_T: begin if (Address <= 16'hFF) begin if (SecSiMem[Address] != -1) ReadData = SecSiMem[Address]; else ReadData = 16'bx; end else ReadData = 16'b0; end AS_T: begin if (Address >= 16'h00 && Address <= 16'h0F) begin if (Address == 16'h00) ReadData [15:0]= 16'h01; else if (Address == 16'h01) ReadData [15:0]= 16'h007E; else if (Address == 16'h02) begin ReadData[15:1] = 15'h00; if ( DYB[SecAddr] == 1'b1) ReadData[0] = 1'b0; else ReadData[0] = 1'b1; end else if (Address == 16'h03) ReadData[15:0] = 0; else if (Address == 16'h06) ReadData[15:0] = 16'h0010; else if (Address == 16'h07) begin if ( LockReg[0] == 1'b1) ReadData[15:0] = 16'h00BF; else ReadData[15:0] = 16'h00FF; end else if (Address == 16'h0C) ReadData [15:0]= 16'h0002; else if (Address == 16'h0E) ReadData [15:0]= 16'h0061; else if (Address == 16'h0F) begin if (tmp_char == "1") ReadData [15:0]= 16'h0002; else if (tmp_char == "0") ReadData [15:0]= 16'h0001; end else begin for (i=0; i<=7; i=i+1) ReadData[i] = Reserved1; for (i=8; i<=15; i=i+1) ReadData[i] = Reserved0; end end else begin ReadData = UNDEFINED; $display(" Invalid Autoselect query address "); end end CFI_T: begin ReadData = CFIMem[Address]; end endcase OutputD = ReadData; end endtask task READ_BURST_DATA; input integer BAddr; input integer BSec; input reg[7:0] Targ; integer m; begin case (Targ) Mem_T: begin DOut_burst = 16'bx; if (Mem[BAddr] != -1) DOut_burst = Mem[BAddr]; end SS_T: begin DOut_burst = 16'bx; m= ReturnAddr(BAddr, BSec); if (SecSiMem[m] != -1) DOut_burst = SecSiMem[m]; end AS_T: begin m= ReturnAddr(BAddr, BSec); if (m >= 16'h00 && m <= 16'h0F) begin if (m == 16'h00) DOut_burst[15:0] = 16'h01; else if (m == 16'h01) DOut_burst[15:0] = 16'h007E; else if (m == 16'h02) begin DOut_burst[15:1] = 15'h00; if ( DYB[BSec] == 1'b1 ) DOut_burst[0] = 1'b0; else DOut_burst[0] = 1'b1; end else if (m == 16'h03) DOut_burst[15:0] = 16'h00; else if (m == 16'h06) DOut_burst[15:0] = 16'h0010; else if (m == 16'h07) if (LockReg[0] == 1'b1) DOut_burst[15:0] = 16'h00BF; else DOut_burst[15:0] = 16'h00FF; else if (m == 16'h0C) DOut_burst [15:0]= 16'h0002; else if (m == 16'h0E) DOut_burst [15:0]= 16'h0061; else if (m == 16'h0F) begin if (tmp_char == "0") DOut_burst [15:0]= 16'h0001; else if (tmp_char == "1") DOut_burst [15:0]= 16'h0002; end else begin for (i=0; i<=7; i=i+1) DOut_burst[i] = Reserved1; for (i=8; i<=15; i=i+1) DOut_burst[i] = Reserved0; end end end CFI_T: begin if (BAddr >= 16'h10 && BAddr<= 16'h5B) DOut_burst = CFIMem[BAddr] ; else begin DOut_burst = UNDEFINED; end end endcase end endtask task NEXT_ADDR_LIN; inout integer BAddr; input integer Length; begin BAddr = BAddr +1; if (BAddr % Length == 0) BAddr = BAddr - Length; end endtask task CHECK_END; inout integer CNT; output BEnd; begin CNT = CNT - 1; if (CNT == 0) BEnd = 1; else BEnd = 0; end endtask task NEXT_ADDR; inout integer BAddr; inout integer BSec; input reg[7:0] Targ; begin case (Targ) Mem_T: begin if (BAddr == MemSize) begin BAddr = 0; BSec = 0; end else begin BAddr = BAddr +1; if ((BSec < (SecNum-3) && tmp_char == "0") || (BSec > 3 && tmp_char == "1")) begin if (BAddr % (SecSize64+1) == 0) BSec = BSec +1; end else begin if (BAddr % (SecSize16+1) == 0) BSec = BSec +1; end end end SS_T: begin if (BAddr % 256 == 255) BAddr = BAddr - 255; else BAddr = BAddr +1; end CFI_T: begin if (BAddr % 16'h80 == 16'h5B) BAddr = BAddr-16'h5B; else BAddr = BAddr +1; end AS_T: begin if (BAddr % 16'h80 == 16'h0F) BAddr = 0; else BAddr = BAddr +1; end endcase end endtask task CheckBoundary; inout BusyBound; input integer BurstAddr; integer BankCHECK; integer SectorCHECK; integer PageCHECK; begin BankCHECK = ReturnBank((BurstAddr+1) % (MemSize+1)); SectorCHECK = ReturnSectorID((BurstAddr+1) % (MemSize+1)); if ((current_state == ESP && SectorCHECK == SA_ERS) || (current_state == ESPS && BankCHECK == BA_ERS) || (current_state == SERS_EXEC && BankCHECK == BA_ERS) || (current_state == PGMS && ((BankCHECK == BA_PGM) || (ESP_ACT && SectorCHECK == SA_ERS))) || (current_state == WR2BUFF_ABORT && ((BankCHECK == BA_PGM) || (ESP_ACT && SectorCHECK == SA_ERS))) || (current_state == PSPS && ((BankCHECK == BA_PGM) || (ESP_ACT && SectorCHECK == SA_ERS))) || (current_state == PSP &&((SectorCHECK == SA_PGM ) || (ESP_ACT && SectorCHECK == SA_ERS))) || (current_state == AS && ((BankCHECK == BA_AS) || (SecAddr == SA_PGM && PSP_ACT) || (ESP_ACT && SecAddr == SA_ERS))) || (current_state == ESP_AS && BankCHECK == BA_AS) || (current_state == PSP_AS && BankCHECK == BA_AS) || (current_state == LOCKREG_CMDSET && BankCHECK == 0) || (current_state == DYB_CMDSET && (BankCHECK == BA_DYB || (SecAddr == SA_PGM && PSP_ACT) || (ESP_ACT && SecAddr == SA_ERS))) || (current_state == OTP && (SectorCHECK == 0 || (SecAddr == SA_PGM && PSP_ACT))) ) BusyBound = 1; BusyBound = BusyBound && (ReturnBank(BurstAddr) != BankCHECK || ReturnSectorID(BurstAddr) != SectorCHECK ); end endtask function integer ReturnAddr; input integer ADDR; input integer SADDR; begin if (SADDR <= 3 && (tmp_char == "1")) ReturnAddr = ADDR % (SecSize16+1); else if (tmp_char == "1") ReturnAddr = ADDR % (SecSize64+1); else if (SADDR < (SecNum-3) && (tmp_char=="0")) ReturnAddr = ADDR % (SecSize64+1); else ReturnAddr = ADDR % (SecSize16+1); end endfunction function integer ReturnSectorID; input integer ADDR; integer conv; begin conv = ADDR / (SecSize64+1); if (conv == 0 && (tmp_char == "1")) ReturnSectorID = (ADDR - sgsaB[0]) / (SecSize16+1); else if (tmp_char == "1") ReturnSectorID = 3+conv; else if (conv == (SecNum-3) && (tmp_char=="0")) ReturnSectorID = SecNum - 3 + (ADDR - sgsaT[1])/(SecSize16+1); else ReturnSectorID = conv; end endfunction function integer ReturnBuffPage; input integer ADDR; begin ReturnBuffPage = ADDR / (WrBuffLength+1); end endfunction function integer ReturnBank; input integer ADDR; begin ReturnBank = ADDR / (BankSize+1); end endfunction always @(negedge AVDNeg) begin falling_edge_AVDNeg = 1; #1 falling_edge_AVDNeg = 0; end always @(posedge AVDNeg) begin rising_edge_AVDNeg = 1; #1 rising_edge_AVDNeg = 0; end always @(posedge gWE_n) begin rising_edge_gWE_n = 1; #1 rising_edge_gWE_n = 0; end always @(negedge gWE_n) begin falling_edge_gWE_n = 1; #1 falling_edge_gWE_n = 0; end always @(posedge gCE_n) begin rising_edge_gCE_n = 1; #1 rising_edge_gCE_n = 0; end always @(negedge gCE_n) begin falling_edge_gCE_n = 1; #1 falling_edge_gCE_n = 0; end always @(posedge CENeg) begin rising_edge_CENeg = 1; #1 rising_edge_CENeg = 0; end always @(negedge gOE_n) begin falling_edge_gOE_n= 1; #1 falling_edge_gOE_n = 0; end always @(posedge gOE_n) begin rising_edge_gOE_n = 1; #1 rising_edge_gOE_n = 0; end always @(negedge CENeg) begin falling_edge_CENeg = 1; #1 falling_edge_CENeg = 0; end always @(posedge CLK) begin rising_edge_CLK = 1; #1 rising_edge_CLK = 0; end always @(negedge OENeg) begin falling_edge_OENeg = 1; #1 falling_edge_OENeg = 0; end always @(A) begin A_event = 1; #1 A_event = 0; end always @(posedge RESETNeg) begin rising_edge_RESETNeg = 1; #1 rising_edge_RESETNeg = 0; end always @(negedge RESETNeg) begin falling_edge_RESETNeg = 1; #1 falling_edge_RESETNeg = 0; end always @(posedge START_in) begin rising_edge_START_in = 1; #1 rising_edge_START_in = 0; end always @(posedge READ) begin rising_edge_READ =1; #1 rising_edge_READ = 0; end always @(negedge READ) begin falling_edge_READ =1; #1 falling_edge_READ = 0; end always @(posedge reseted) begin rising_edge_reseted = 1; #1 rising_edge_reseted = 0; end always @(posedge PSTART) begin rising_edge_PSTART = 1; #1 rising_edge_PSTART = 0; end always @(posedge PSUSP) begin rising_edge_PSUSP = 1; #1 rising_edge_PSUSP = 0; end always @(posedge PRES) begin rising_edge_PRES = 1; #1 rising_edge_PRES = 0; end always @(posedge ESTART) begin rising_edge_ESTART = 1; #1 rising_edge_ESTART = 0; end always @(posedge ESUSP) begin rising_edge_ESUSP = 1; #1 rising_edge_ESUSP = 0; end always @(posedge ERES) begin rising_edge_ERES = 1; #1 rising_edge_ERES = 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 @(posedge PDONE) begin rising_edge_PDONE = 1; #1 rising_edge_PDONE = 0; end always @(posedge PERR) begin rising_edge_PERR = 1; #1 rising_edge_PERR = 0; end always @(posedge START_out) begin rising_edge_START_out = 1; #1 rising_edge_START_out = 0; end always @(negedge RST) begin falling_edge_RST = 1; #1 falling_edge_RST = 0; end always @(negedge BURST) begin falling_edge_BURST = 1; #1 falling_edge_BURST = 0; end always @(negedge PERR) begin falling_edge_PERR = 1; #1 falling_edge_PERR = 0; end always @(negedge EERR) begin falling_edge_EERR = 1; #1 falling_edge_EERR = 0; end always @(posedge CLKMerge) begin rising_edge_CLKMerge = 1; #1 rising_edge_CLKMerge = 0; end always @(posedge OENeg) begin rising_edge_OENeg = 1; #1 rising_edge_OENeg = 0; end always @(posedge RST_in) begin rising_edge_RST_in = 1; #1 rising_edge_RST_in = 0; end always @(~oe) begin if (~oe) FlagOE = 1'b1; end always @(~BURST) begin if (~BURST) FlagBURST = 1'b1; end always @(next_state) begin next_state_event = 1; #1 next_state_event = 0; end always @(PERR) begin PERR_EVENT = 1; #1 PERR_EVENT = 0; end always @(EERR) begin EERR_EVENT = 1; #1 EERR_EVENT = 0; end always @(DIn) begin Din_event = 1; #1 Din_event = 0; end always @(negedge ReadINIT) begin falling_edge_ReadINIT = 1; #1 falling_edge_ReadINIT = 0; end reg BuffInOE, BuffInCE, BuffInADDRINasyn, BuffInADDRINsyn; wire BuffOutOE, BuffOutCE, BuffOutADDRINasyn, BuffOutADDRINsyn; BUFFER BUFOENeg (BuffOutOE , BuffInOE); BUFFER BUFCENeg (BuffOutCE , BuffInCE); BUFFER BUFADDRasync (BuffOutADDRINasyn , BuffInADDRINasyn); BUFFER BUFADDRsync (BuffOutADDRINsyn, BuffInADDRINsyn); initial begin BuffInOE = 1'b1; BuffInCE = 1'b1; BuffInADDRINasyn = 1'b1; BuffInADDRINsyn = 1'b1; end always @(posedge BuffOutOE) begin OEDQ_01 = $time; end always @(posedge BuffOutCE) begin CEDQ_01 = $time; end always @(posedge BuffOutADDRINasyn) begin ADDRDQINasyn_01 = $time; end always @(posedge BuffOutADDRINsyn) begin ADDRDQINsyn_01 = $time; end endmodule module BUFFER (OUT,IN); input IN; output OUT; buf (OUT, IN); endmodule