////////////////////////////////////////////////////////////////////////////// // File name : s29vs256r.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 Sep 29 Initial Release // ////////////////////////////////////////////////////////////////////////////// // PART DESCRIPTION: // // Library: FLASH // Technology: FLASH MEMORY // Part: S29VS256R // // Description: 256 Megabit (16M x 16 bit) 1.8 V // Burst Simultaneous Read/Write // Multiplexed MirrorBit Flash Memory ////////////////////////////////////////////////////////////////////////////// // 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 module s29vs256r ( A23, A22, A21, A20, A19, A18, A17, A16, ADQ15, ADQ14, ADQ13, ADQ12, ADQ11, ADQ10, ADQ9, ADQ8, ADQ7, ADQ6, ADQ5, ADQ4, ADQ3, ADQ2, ADQ1, ADQ0, CLK, RESETNeg, CENeg, OENeg, WENeg, AVDNeg, VPP, RDY ); //////////////////////////////////////////////////////////////////////////// // Port / Part Pin Declarations // //////////////////////////////////////////////////////////////////////////// input A23; input A22; 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 CLK; input RESETNeg; input CENeg; input OENeg; input WENeg; input AVDNeg; input VPP; output RDY; // interconnect path delay signals wire A23_ipd; wire A22_ipd; wire A21_ipd; wire A20_ipd; wire A19_ipd; wire A18_ipd; wire A17_ipd; wire A16_ipd; 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 [23:0] A; assign A = { A23_ipd, A22_ipd, A21_ipd, A20_ipd, A19_ipd, A18_ipd, A17_ipd, A16_ipd, 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 CLK_ipd; wire RESETNeg_ipd; wire CENeg_ipd; wire OENeg_ipd; wire WENeg_ipd; wire AVDNeg_ipd; wire VPP_ipd; wire DQ15_pass; wire DQ14_pass; wire DQ13_pass; wire DQ12_pass; wire DQ11_pass; wire DQ10_pass; wire DQ9_pass; wire DQ8_pass; wire DQ7_pass; wire DQ6_pass; wire DQ5_pass; wire DQ4_pass; wire DQ3_pass; wire DQ2_pass; wire DQ1_pass; wire DQ0_pass; reg [15:0] Dout_pass = 16'bz; 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; parameter UserPreload = 1'b0; parameter mem_file_name = "none"; parameter secsi_file_name = "none"; parameter TimingModel = "DefaultTimingModel"; parameter PartID = "s29vs256r"; parameter MaxData = 16'hffff; parameter MemSize = 30'hffffff; parameter SecNum = 258; parameter BankNum = 7; parameter SecGroupNum = 1; parameter SecSize64 = 16'hffff; parameter SecSize16 = 16'h3fff; parameter BankSize = 30'h1fffff; parameter HiAddrBit = 23; parameter WrBuffLength = 31; parameter WrBuffPgNum = 30'h7ffff; parameter TBD = 16'h0000; parameter Reserved0 = 0; parameter Reserved1 = 1; //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;//stores "0" or "1" character integer found = 1'b0; // 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 IDLE_RST = 8'd0; parameter ERASE_ENTRY = 8'd1; parameter SL_ENTRY = 8'd2; parameter SSR_LOCK_ENTRY = 8'd3; parameter SecSi_ENTRY = 8'd4; parameter CR_ENTRY = 8'd5; parameter W2B_ENTRY = 8'd6; parameter ID_CFI_ENTRY = 8'd7; parameter BC_ENTRY = 8'd8; parameter CERS = 8'd9; parameter SERS = 8'd10; parameter SL_Change = 8'd11; parameter W2B_WC = 8'd12; parameter SERS_SL = 8'd13; parameter LOCK_RANGE = 8'd14; parameter W2BUF_PG = 8'd15; parameter WB_LOADED = 8'd16; parameter SERS_SUS = 8'd17; parameter PGM = 8'd18; parameter PGM_SL = 8'd19; parameter PGM_SUS = 8'd20; // states reg [9:0] current_state = IDLE_RST; reg [9:0] next_state = IDLE_RST; reg [7:0] RD_MODE = SYNCR; reg PoweredUp = 0; reg ASYN = 1; // asynchronous mode // FSM control signals reg ESP_ACT = 0; reg PGM_ACT = 0; reg LOCK_ACT = 0; reg CR_ACT = 0; reg SecSi = 0; reg PDONE = 1; // Programming done reg PSTART = 0; // Start programming reg PSUSP = 0; // suspend programming reg PRES = 0; // Resume Programming reg EDONE = 1; // Erase Done reg ESTART = 0; // Start Erase reg ESUSP = 0; // Suspend Erase reg ERES = 0; // Resume Erase reg BCDONE = 1; // Blank Check Done reg CEDONE = 1; // Chip Erase Done reg WRITE = 1; reg READ = 1; reg BURST = 1; reg ReadINIT = 1; reg [15:0] OutputD, DOut_burst; // 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 [15:0] Dout_zd = 16'bz; reg RDY_zd = 1'bz; // Access time variables reg FROMCE = 0; reg FROMOE = 0; integer OEDQ_01_ASYN; integer OEDQ_01_SYN; integer OEDQ_01; integer CEDQ_01; integer ADDRDQIN_01; integer ADDRDQPAGE_01; time OEDQ_t = 0; time CEDQ_t = 0; time ADDRDQ_t = 0; time ADDR_event = 0; reg[15:0] TempData; integer Addr, SecAddr, BankID, BurstSec; integer PrevAddr; // Write page buffer address integer BuffPageAddr; integer sgsaT [0:SecGroupNum]; integer sgsaB [0:SecGroupNum]; // Data integer D_tmp, BA_ERS, BA_PGM, SA_ERS, SA_SSR, SA_SecSi, SA_CR; integer SA_PGM, SA_SR, SA_ID_CFI, SA_BC, PA_PGM, BA_BC; integer SL_REG = -2; // glitch protection reg gWE_n = 1; reg gCE_n = 1; reg gOE_n = 1; reg gAVD_n = 1; reg AddrREF = 0; reg CLKMerge = 0; reg IN_W_ELAPSED; reg DATA_DELAY; reg RST = 0; reg reseted = 0; integer SecSiMem [0 : 255]; integer CFIMem [16 : 103]; integer Mem [0:MemSize]; reg [15:0] ConfReg0 = 16'b1101111101001000; reg [15:0] SSR_LOCK_REG = 16'b1111111111111101; // write buffer signals integer WrBuffData [0 : WrBuffLength]; integer WrBuffAddr [0 : WrBuffLength]; integer WrBuffCnt, WC, BurstDelay, WS_Initial; reg Check_freq; reg deq; //Sectors selected for erasure reg STAT_ACT = 0; reg D_pass = 1; reg Viol, BurstStarted; integer DelayCycSwitch, BurstAddr,RDCnt,WS_Boundary,WS_Latency; integer tmpaddr, tmpdata; /////////////////////////////////////////////////////////////////////////////// //Interconnect Path Delay Section /////////////////////////////////////////////////////////////////////////////// buf (A23_ipd, A23); buf (A22_ipd, A22); buf (A21_ipd, A21); buf (A20_ipd, A20); buf (A19_ipd, A19); buf (A18_ipd, A18); buf (A17_ipd, A17); buf (A16_ipd, A16); 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 (CLK_ipd , CLK ); buf (RESETNeg_ipd , RESETNeg ); buf (CENeg_ipd , CENeg ); buf (OENeg_ipd , OENeg ); buf (WENeg_ipd , WENeg ); buf (AVDNeg_ipd , AVDNeg ); 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 CENeg_CLK_check; assign CENeg_CLK_check = ~ConfReg0[15] && ~AVDNeg ; wire ADQ0_CLK_check; assign ADQ0_CLK_check = ~ConfReg0[15] && ~AVDNeg && CENeg; wire AVDNeg_CLK_check; assign AVDNeg_CLK_check = ~ConfReg0[15] && ~CENeg && ~AVDNeg ; wire CENeg_low1; assign CENeg_low1 = ~CENeg ; wire CENeg_low; assign CENeg_low = ~CENeg && deg; wire ADQ0_WENeg_check; assign ADQ0_WENeg_check = ConfReg0[15] && ~CENeg && OENeg && ~AVDNeg; wire ADQ0_CENeg_check; assign ADQ0_CENeg_check = ConfReg0[15] && ~WENeg && OENeg && ~AVDNeg; wire CLK_check; assign CLK_check = ~ConfReg0[15]; 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; // tce, tcez specparam tpd_CENeg_ADQ0_SYN_EQ_1 = 1; // tce, tcez specparam tpd_OENeg_ADQ0_SYN_EQ_0 = 1; // toe, toez specparam tpd_OENeg_ADQ0_SYN_EQ_1 = 1; // toe, toez specparam tpd_CLK_ADQ0 = 1; // tbacc specparam tpd_CENeg_RDY_SYN_EQ_0 = 1; // tcr, tcez specparam tpd_CENeg_RDY_SYN_EQ_1 = 1; // tcr, tcez specparam tpd_OENeg_RDY = 1; // toe specparam tpd_CLK_RDY = 1; // tracc // tsetup values specparam tsetup_CENeg_CLK = 1; // tces edge / specparam tsetup_ADQ0_CLK = 1; // tacs edge / specparam tsetup_ADQ0_AVDNeg = 1; // tas edge / specparam tsetup_AVDNeg_CLK = 1; // tavc edge / specparam tsetup_AVDNeg_WENeg = 1; // tvlwh edge / specparam tsetup_ADQ0_WENeg = 1; // tds edge / specparam tsetup_AVDNeg_OENeg = 1; // tavdo edge \ specparam tsetup_WENeg_OENeg = 1; // tweh edge \ specparam tsetup_WENeg_AVDNeg = 1; // twea edge \ specparam tsetup_OENeg_WENeg = 1; // tweh edge \ specparam tsetup_CENeg_WENeg = 1; // tcs edge \ specparam tsetup_RESETNeg_CENeg = 1; // trh edge \ specparam tsetup_ADQ0_CENeg = 1; specparam tsetup_WENeg_CENeg = 1; specparam tsetup_CENeg_AVDNeg = 1; specparam tsetup_RESETNeg_OENeg = 1; // thold values specparam thold_CENeg_RESETNeg = 1; // trph edge \ specparam thold_ADQ0_CLK = 1; // tach edge / specparam thold_ADQ0_AVDNeg = 1; // taavdh edge / specparam thold_AVDNeg_CLK = 1; // tavd edge / specparam thold_ADQ0_CENeg = 1; specparam thold_OENeg_RESETNeg = 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 specparam tpw_CENeg_negedge = 1; specparam tpw_CENeg_posedge = 1; // tperiod values specparam tperiod_WENeg_posedge = 1; // twc specparam tperiod_WENeg_negedge = 1; specparam tperiod_CENeg_posedge = 1; specparam tperiod_CENeg_negedge = 1; specparam tperiod_CLK = 1; // tclk // tdevice values: values for internal delays `ifdef SPEEDSIM specparam tdevice_WRBO = 9400000; // Write Buffer Program // Sector Erase Operation specparam tdevice_SEO64 = 1300000; // 64 Kword sector specparam tdevice_SEO16 = 600000; // 16 Kword sector specparam tdevice_IACC = 75000; // Initial access delay tIA // Program/Erase Suspend Timeout tESL, tPSL specparam tdevice_START = 30000000; specparam tdevice_BCHECK = 1000000000; specparam tdevice_ACCT = 80000; `else specparam tdevice_WRBO = 9400000; // Write Buffer Program // Sector Erase Operation specparam tdevice_SEO64 = 1300000000; // 64 Kword sector specparam tdevice_SEO16 = 600000000; // 16 Kword sector specparam tdevice_IACC = 75000; // Initial access delay tIA // Program/Erase Suspend Timeout tESL, tPSL specparam tdevice_START = 30000000; specparam tdevice_BCHECK = 1000000000; specparam tdevice_ACCT = 80000; `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 (FROMOE && ASYN) (OENeg => ADQ0) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ1) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ2) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ3) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ4) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ5) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ6) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ7) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ8) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ9) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ10) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ11) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ12) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ13) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ14) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ASYN) (OENeg => ADQ15) = tpd_OENeg_ADQ0_SYN_EQ_0; if (FROMOE && ~ASYN) (OENeg => ADQ0) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ1) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ2) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ3) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ4) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ5) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ6) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ7) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ8) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ9) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ10) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ11) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ12) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ13) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ14) = tpd_OENeg_ADQ0_SYN_EQ_1; if (FROMOE && ~ASYN) (OENeg => ADQ15) = tpd_OENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ0) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ1) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ2) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ3) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ4) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ5) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ6) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ7) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ8) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ9) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ10) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ11) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ12) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ13) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ14) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ASYN) (CENeg => ADQ15) = tpd_CENeg_ADQ0_SYN_EQ_0; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ0) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ1) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ2) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ3) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ4) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ5) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ6) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ7) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ8) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ9) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ10) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ11) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ12) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ13) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ14) = tpd_CENeg_ADQ0_SYN_EQ_1; if ((FROMCE || D_pass) && ~ASYN) (CENeg => ADQ15) = tpd_CENeg_ADQ0_SYN_EQ_1; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ0) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ1) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ2) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ3) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ4) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ5) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ6) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ7) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ8) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ9) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ10) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ11) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ12) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ13) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ14) = tpd_CLK_ADQ0; if (~CENeg && ~ASYN && IN_W_ELAPSED && CLK && (RD_MODE == CONTINUOUS || RD_MODE == LINEAR)) (CLK => ADQ15) = tpd_CLK_ADQ0; if (ASYN) (CENeg => RDY) = tpd_CENeg_RDY_SYN_EQ_0; if (~ASYN) (CENeg => RDY) = tpd_CENeg_RDY_SYN_EQ_1; if (~CENeg && ~ASYN) (OENeg => RDY) = tpd_OENeg_RDY; if (~CENeg && ~ASYN && RDY_zd !== 1'bz && CLK) (CLK => RDY) = tpd_CLK_RDY; if (~RESETNeg) (RESETNeg => RDY) = tpd_RESETNeg_ADQ0; //////////////////////////////////////////////////////////////////////////// // Timing Violation // //////////////////////////////////////////////////////////////////////////// $setup (CENeg, posedge CLK &&& CENeg_CLK_check,tsetup_CENeg_CLK); $setup (ADQ0, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ1, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ2, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ3, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ4, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ5, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ6, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ7, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ8, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ9, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ10, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ11, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ12, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ13, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ14, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (ADQ15, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A16, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A17, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A18, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A19, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A20, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A21, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A22, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (A23, posedge CLK &&& ADQ0_CLK_check, tsetup_ADQ0_CLK); $setup (AVDNeg, posedge CLK &&& AVDNeg_CLK_check, tsetup_AVDNeg_CLK); $setup (ADQ0, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ1, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ2, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ3, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ4, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ5, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ6, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ7, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ8, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ9, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ10, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ11, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ12, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ13, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ14, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ15, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A16, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A17, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A18, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A19, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A20, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A21, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A22, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (A23, posedge AVDNeg &&& ADQ0_CENeg_check, tsetup_ADQ0_AVDNeg); $setup (ADQ0, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ1, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ2, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ3, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ4, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ5, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ6, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ7, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ8, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ9, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ10, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ11, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ12, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ13, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ14, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ15, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A16, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A17, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A18, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A19, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A20, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A21, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A22, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (A23, negedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ0, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ1, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ2, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ3, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ4, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ5, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ6, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ7, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ8, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ9, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ10, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ11, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ12, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ13, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ14, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ15, posedge WENeg &&& ADQ0_WENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ0, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ1, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ2, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ3, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ4, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ5, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ6, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ7, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ8, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ9, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ10, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ11, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ12, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ13, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ14, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ15, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_WENeg); $setup (ADQ0, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ1, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ2, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ3, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ4, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ5, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ6, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ7, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ8, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ9, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ10, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ11, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ12, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ13, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ14, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (ADQ15, posedge CENeg &&& ADQ0_CENeg_check, tsetup_ADQ0_CENeg); $setup (AVDNeg, posedge WENeg &&& CENeg_low1, tsetup_AVDNeg_WENeg); $setup (CENeg, negedge WENeg, tsetup_CENeg_WENeg); $setup (WENeg, negedge CENeg, tsetup_WENeg_CENeg); $setup (OENeg, negedge WENeg &&& CENeg_low1, tsetup_OENeg_WENeg); $setup (CENeg, posedge AVDNeg &&& CENeg_low1, tsetup_CENeg_AVDNeg); $setup (WENeg, negedge AVDNeg, tsetup_WENeg_AVDNeg); $setup (RESETNeg, negedge OENeg, tsetup_RESETNeg_OENeg); $setup (RESETNeg, negedge CENeg, tsetup_RESETNeg_CENeg); $setup (AVDNeg, negedge OENeg &&& CENeg_low1, tsetup_AVDNeg_OENeg); $setup (WENeg, negedge OENeg &&& CENeg_low1, tsetup_WENeg_OENeg); $hold (negedge RESETNeg, OENeg, thold_OENeg_RESETNeg); $hold (negedge RESETNeg, CENeg, thold_CENeg_RESETNeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ0, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ1, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ2, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ3, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ4, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ5, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ6, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ7, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ8, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ9, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ10, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ11, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ12, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ13, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ14, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, ADQ15, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A16, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A17, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A18, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A19, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A20, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A21, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A22, thold_ADQ0_CENeg); $hold (negedge CENeg &&& ADQ0_CENeg_check, A23, thold_ADQ0_CENeg); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ0, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ1, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ2, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ3, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ4, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ5, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ6, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ7, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ8, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ9, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ10, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ11, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ12, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ13, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ14, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, ADQ15, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A16, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A17, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A18, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A19, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A20, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A21, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A22, thold_ADQ0_AVDNeg, Viol); $hold (posedge AVDNeg &&& ADQ0_CENeg_check, A23, thold_ADQ0_AVDNeg, Viol); $hold (posedge CLK &&& AVDNeg_CLK_check, AVDNeg, thold_AVDNeg_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ0, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ1, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ2, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ3, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ4, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ5, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ6, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ7, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ8, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ9, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ10, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ11, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ12, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ13, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ14, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, ADQ15, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A16, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A17, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A18, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A19, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A20, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A21, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A22, thold_ADQ0_CLK, Viol); $hold (posedge CLK &&& ADQ0_CLK_check, A23, thold_ADQ0_CLK, Viol); $width (negedge AVDNeg, tpw_AVDNeg_negedge); $width (negedge RESETNeg, tpw_RESETNeg_negedge); $width (posedge WENeg, tpw_WENeg_posedge); $width (negedge WENeg, tpw_WENeg_negedge); $width (posedge CENeg, tpw_CENeg_posedge); $width (negedge CENeg, tpw_CENeg_negedge); $width (posedge CLK &&& CLK_check, tpw_CLK_posedge); $width (negedge CLK &&& CLK_check, tpw_CLK_negedge); $period(posedge WENeg, tperiod_WENeg_posedge); $period(posedge CENeg, tperiod_CENeg_posedge); $period(posedge CLK &&& CLK_check, tperiod_CLK); endspecify //tdevice parameters aligned to model timescale //32bits exceeded time tdevice_SEO64_ts = tdevice_SEO64 * 1000; time tdevice_SEO16_ts = tdevice_SEO16 * 1000; //////////////////////////////////////////////////////////////////////////////// // Main Behavior Block // //////////////////////////////////////////////////////////////////////////////// integer AddressLatched, WrAddressLatched; reg READCYCLE, LATCHED, AVDLATCHED, AsynWrAddLatch; time elapsed, duration, start, wrbo, seo16, seo64; integer i, Data, DataLo, AddrCom, j, new_int; reg [16:0] new_bit; reg BURST_TR, SYNCREAD; reg [15:0] Status = 16'b0000000010000000; reg oe = 0; reg ER_FLAG = 0; reg RDY_temp, BOUNDARY_CROSS, BURST_END, NO_PROGRESS,BusyBound; integer BurstLength, DelayCyc_CNT, LatencyAddr; integer old_int, old_bit; reg INITIAL = 0; 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_CLK, falling_edge_OENeg, A_event, Din_event; reg rising_edge_RESETNeg, falling_edge_RESETNeg; 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 rising_edge_BCDONE; reg falling_edge_WRITE, rising_edge_CEDONE; reg rising_edge_EDONE, rising_edge_PDONE; reg rising_edge_START_out, falling_edge_RST; reg falling_edge_BURST, rising_edge_OENeg; reg rising_edge_CLKMerge; reg next_state_event, falling_edge_ReadINIT; time OENeg_event = 0; time CENeg_event = 0; reg LockRangeDone = 0; reg LockRange = 0; reg A6Lock = 0; reg PR_FLAG = 0; integer SLA_Lo = -1; integer SLA_Hi = -1; integer SLA_temp, BoundarySwitch; parameter Mem_T = 4'd0; parameter SS_T = 4'd1; parameter ID_CFI_T = 4'd2; reg [7:0] ReadTarget; // Power Up time tVCS is 30 us initial begin : PowerupTime PoweredUp = 1'b0; #300000000 PoweredUp = 1'b1; sgsaT[0] = 30'h000000; sgsaT[1] = 30'hff0000; sgsaB[0] = 30'h000000; sgsaB[1] = 30'h010000; 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 CEDQ_t = CENeg_event + CEDQ_01; OEDQ_t = OENeg_event + OEDQ_01_ASYN; if (ConfReg0[15] == 1) ADDRDQ_t = ADDR_event + ADDRDQIN_01; //tacc else ADDRDQ_t = ADDR_event + tdevice_IACC; 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 @(ConfReg0) begin if (ConfReg0[15]) ASYN = 1; else if (~ConfReg0[15]) ASYN = 0; 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 #(50000-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) begin: StateTransition if (PoweredUp) begin if (RESETNeg) begin if (next_state_event) current_state = next_state; reseted = 1; end else if (~RESETNeg && ~RST) begin // no state transition while RESETNeg is low current_state = IDLE_RST; reseted = 0; end end else begin current_state = IDLE_RST; 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 always @(negedge AVDNeg_ipd) begin: gAVD_n_f #3000 gAVD_n = AVDNeg_ipd; end always @(posedge AVDNeg_ipd) begin disable gAVD_n_f; gAVD_n = AVDNeg_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 - 1) IACC_out = 1; 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, rising_edge_CLK, A_event, falling_edge_OENeg) begin : BusCycleDecode // Write address latch if (rising_edge_AVDNeg && ~CENeg && OENeg) WrAddressLatched = {A[HiAddrBit:16], Din}; 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 || (A_event && ~AVDNeg) || (Din_event && ~AVDNeg)) && WENeg) begin // tACC count AddrREF = ~AddrREF; ADDR_event = $time; end if (rising_edge_AVDNeg && ~CENeg && OENeg) AddressLatched = {A[HiAddrBit:16], Din}; 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 READCYCLE = 1; LATCHED = 1; AddressLatched = {A[HiAddrBit:16], 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; if (rising_edge_reseted) PDONE = 1; // reset done, programing terminated else if (reseted) begin if (rising_edge_PSTART && PDONE) begin start = $time; elapsed = 0; duration = (WrBuffCnt + 1) * wrbo; PDONE = 0; -> pdone_event; 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 start = $time; elapsed = 0; if ((SA_ERS<=3 && tmp_char == "1") || (SA_ERS >= (SecNum -3) && tmp_char == "0")) duration = seo16; else duration = seo64; elapsed = 0; EDONE = 0; -> edone_event; start = $time; 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 time CLK_PER = 0; time LAST_CLK = 0; // 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) || (CLK_PER < 96150 && WS_Initial < 10) || (CLK_PER < 8333 && WS_Initial < 11) || (CLK_PER < 7462 && WS_Initial < 12)) 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_CEDONE, rising_edge_EDONE, rising_edge_START_out, rising_edge_PDONE, rising_edge_BCDONE) begin : StateGen if (falling_edge_WRITE) begin Data = D_tmp; DataLo = D_tmp % 12'h100; AddrCom = Addr % 16'h1000; end if (reseted != 1) next_state = current_state; else begin case (current_state) IDLE_RST: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h555 && DataLo == 8'h80) next_state = ERASE_ENTRY; else if (((AddrCom % 12'h100) == 12'h55) && ((DataLo == 8'h90) || (DataLo == 8'h98)) && (BankID == 0)) next_state = ID_CFI_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'h60) next_state = SL_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'h40) next_state = SSR_LOCK_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'h88) next_state = SecSi_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'hD0) next_state = CR_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'h25) next_state = W2B_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'h33) next_state = BC_ENTRY; else next_state = IDLE_RST; end end ERASE_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h2AA && DataLo == 8'h10 && SecAddr == SA_ERS && (SL_REG == 0 || SL_REG == -2) && VPP != 0 && ~LockRangeDone) next_state = CERS; else if (AddrCom == 12'h2AA && DataLo == 8'h30 && SecAddr == SA_ERS && (SecAddr == SL_REG || SL_REG == -2) && VPP != 0) next_state = SERS; else if ((DataLo % 8'h10) == 8'hC) begin end else next_state = IDLE_RST; end end SL_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h2AA && DataLo == 8'h60) next_state = SL_Change; else if ((DataLo % 8'h10) == 8'hC) begin end else if (ESP_ACT) next_state = SERS_SUS; else if (PGM_ACT) next_state = PGM_SUS; else next_state = IDLE_RST; end end SSR_LOCK_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h555 && DataLo == 8'h25 && SecAddr == SA_SSR) next_state = W2B_ENTRY; else if (DataLo == 8'hf0) next_state = IDLE_RST; end end SecSi_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h555 && DataLo == 8'h25 && SecAddr == SA_SecSi) next_state = W2B_ENTRY; else if (DataLo == 8'hf0) next_state = IDLE_RST; end end CR_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h555 && DataLo == 8'h25 && SecAddr == SA_CR) next_state = W2B_ENTRY; else if (DataLo == 8'hf0) next_state = IDLE_RST; end end W2B_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h2AA && SecAddr == SA_PGM && (((SecAddr == SL_REG || SL_REG == -2) && VPP != 0) || (SecSi && VPP != 0) || LOCK_ACT || CR_ACT) && !(SecSi && SSR_LOCK_REG[0] == 0) && !(LOCK_ACT && DataLo >0) && !(CR_ACT && DataLo >0) && !(ESP_ACT && SecAddr == SA_ERS)) next_state = W2B_WC; else if ((DataLo % 8'h10) == 8'hC) begin end else if (ESP_ACT) next_state = SERS_SUS; else if (LOCK_ACT) next_state = SSR_LOCK_ENTRY; else if (CR_ACT) next_state = CR_ENTRY; else if (SecSi) next_state = SecSi_ENTRY; else begin next_state = IDLE_RST; end end end ID_CFI_ENTRY: begin if (falling_edge_WRITE) begin if (DataLo == 8'hf0) next_state = IDLE_RST; end end BC_ENTRY: begin if (rising_edge_BCDONE) next_state = IDLE_RST; end CERS: begin if (rising_edge_CEDONE) begin next_state = IDLE_RST; end end SERS: begin if (rising_edge_EDONE) next_state = IDLE_RST; else if (falling_edge_WRITE) begin if (DataLo == 8'hB0) next_state = SERS_SL; end end SL_Change: begin if (falling_edge_WRITE) begin if (DataLo == 8'h61) next_state = LOCK_RANGE; else if ((DataLo % 8'h10) == 8'hC) begin end else if (ESP_ACT) next_state = SERS_SUS; else if (PGM_ACT) next_state = PGM_SUS; else next_state = IDLE_RST; end end W2B_WC: begin if (falling_edge_WRITE) begin if (SecAddr == SA_PGM && !(SecSi && (ReturnAddr(Addr, SA_SecSi) < 128 || ReturnAddr(Addr,SA_SecSi) > 255)) && !(LOCK_ACT && ((AddrCom % 12'h100) != 0)) && !(CR_ACT && ((AddrCom % 12'h100) > 0)) && WC == 0) next_state = WB_LOADED; else if (SecAddr == SA_PGM && !(SecSi && (ReturnAddr(Addr,SA_SecSi) < 128 || ReturnAddr(Addr,SA_SecSi) > 255)) && !((Addr+WC) / (WrBuffLength+1)> Addr / (WrBuffLength+1)) && ~LOCK_ACT && ~CR_ACT) next_state = W2BUF_PG; else if ((DataLo % 8'h10) == 8'hC) begin end else if (ESP_ACT) next_state = SERS_SUS; else if (LOCK_ACT) next_state = SSR_LOCK_ENTRY; else if (CR_ACT) next_state = CR_ENTRY; else if (SecSi) next_state = SecSi_ENTRY; else next_state = IDLE_RST; end end SERS_SL : begin if (rising_edge_START_out) next_state = SERS_SUS; end LOCK_RANGE: begin if (falling_edge_WRITE) begin if ((DataLo % 8'h10) == 8'hC) begin end else if (ESP_ACT) next_state = SERS_SUS; else if (PGM_ACT) next_state = PGM_SUS; else next_state = IDLE_RST; end end W2BUF_PG: begin if (falling_edge_WRITE) begin if (!(Addr == PrevAddr + 1)) begin if (ESP_ACT) next_state = SERS_SUS; else if (SecSi) next_state = SecSi_ENTRY; else next_state = IDLE_RST; end else if (WC == 0) next_state = WB_LOADED; end end WB_LOADED: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h555 && DataLo == 8'h29 && ((WrBuffAddr[WrBuffCnt]/32) == (WrBuffAddr[0]/32)) && SecAddr == SA_PGM && ~CR_ACT) next_state = PGM; else if (AddrCom == 12'h555 && DataLo == 8'h29 && ((WrBuffAddr[WrBuffCnt]/32) == (WrBuffAddr[0]/32)) && SecAddr == SA_PGM && CR_ACT) next_state = CR_ENTRY; else if ((DataLo % 8'h10) == 8'hC) begin end else if (ESP_ACT) next_state = SERS_SUS; else if (LOCK_ACT) next_state = SSR_LOCK_ENTRY; else if (CR_ACT) next_state = CR_ENTRY; else if (SecSi) next_state = SecSi_ENTRY; else next_state = IDLE_RST; end end SERS_SUS: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h000 && DataLo == 8'h30) next_state = SERS; else if (AddrCom == 12'h555 && DataLo == 8'h60) next_state = SL_ENTRY; else if (AddrCom == 12'h555 && DataLo == 8'h25) next_state = W2B_ENTRY; end end PGM: begin if (rising_edge_PDONE) begin if (ESP_ACT) next_state = SERS_SUS; else if (LOCK_ACT) next_state = SSR_LOCK_ENTRY; else if (SecSi) next_state = SecSi_ENTRY; else next_state = IDLE_RST; end else if (falling_edge_WRITE) if (DataLo == 8'h51) next_state = PGM_SL; end PGM_SL: begin if (rising_edge_START_out) next_state = PGM_SUS; end PGM_SUS: begin if (falling_edge_WRITE) if (AddrCom == 12'h000 && DataLo == 8'h50) next_state = PGM; else if (AddrCom == 12'h555 && DataLo == 8'h60) next_state = SL_ENTRY; end endcase end end ///////////////////////////////////////////////////////////////////////// // Main Behavior Process // combinational process for Read Mode Generation ///////////////////////////////////////////////////////////////////////// always @(falling_edge_RST, falling_edge_BURST, rising_edge_gCE_n, falling_edge_AVDNeg, falling_edge_gWE_n, BURST_TR, SYNCREAD) begin : ReadModeGen BURST_TR = 0; SYNCREAD = 0; if (falling_edge_RST && ~RESETNeg) RD_MODE = NOSYNC; if (reseted) begin case (current_state) IDLE_RST: begin if (falling_edge_BURST) begin if (STAT_ACT && SecAddr == SA_SR) SYNCREAD = 1; else BURST_TR = 1; end end ERASE_ENTRY: begin if (falling_edge_BURST) BURST_TR = 1; end SL_ENTRY: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (PGM_ACT && BuffPageAddr == PA_PGM)) SYNCREAD = 1; else BURST_TR = 1; end end SSR_LOCK_ENTRY: begin if (falling_edge_BURST) begin if (SecAddr == SA_SSR) SYNCREAD = 1; else BURST_TR = 1; end end SecSi_ENTRY: begin if (falling_edge_BURST) begin if (SecAddr == SA_SecSi && ReturnAddr(Addr,SA_SecSi) > 8'hff) SYNCREAD = 1; else BURST_TR = 1; end end CR_ENTRY: begin if (falling_edge_BURST) begin if (SecAddr == SA_CR) SYNCREAD = 1; else BURST_TR = 1; end end W2B_ENTRY: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (LOCK_ACT && SecAddr == SA_SSR) || (CR_ACT && SecAddr == SA_CR) || (SecSi && SecAddr == SA_SecSi && Addr > 8'hFF)) SYNCREAD = 1; else BURST_TR = 1; end end ID_CFI_ENTRY: begin if (falling_edge_BURST) begin if (SecAddr == SA_ID_CFI && (ReturnAddr(Addr,SA_ID_CFI) > 8'h67)) SYNCREAD = 1; else BURST_TR = 1; end end BC_ENTRY: begin if (falling_edge_BURST) begin if (BankID == BA_BC || (STAT_ACT && SecAddr == SA_SR)) SYNCREAD = 1; else BURST_TR = 1; end end CERS: begin if (falling_edge_BURST) SYNCREAD = 1; end SERS: begin if (falling_edge_BURST) begin if (BankID == BA_ERS || (STAT_ACT && SecAddr == SA_SR)) SYNCREAD = 1; else BURST_TR = 1; end end SL_Change: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (PGM_ACT && BuffPageAddr == PA_PGM)) SYNCREAD = 1; else BURST_TR = 1; end end W2B_WC: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (LOCK_ACT && SecAddr == SA_SSR) || (CR_ACT && SecAddr == SA_CR) || (SecSi && SecAddr == SA_SecSi && Addr > 8'hFF)) SYNCREAD = 1; else BURST_TR = 1; end end SERS_SL: begin if (falling_edge_BURST) begin if (BankID == BA_ERS || (STAT_ACT && SecAddr == SA_SR)) SYNCREAD = 1; else BURST_TR = 1; end end LOCK_RANGE: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (PGM_ACT && BuffPageAddr == PA_PGM)) SYNCREAD = 1; else BURST_TR = 1; end end W2BUF_PG: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (SecSi && SecAddr == SA_SecSi && Addr > 8'hFF)) SYNCREAD = 1; else BURST_TR = 1; end end WB_LOADED: begin if (falling_edge_BURST) begin if ((ESP_ACT && SecAddr == SA_ERS) || (LOCK_ACT && SecAddr == SA_SSR) || (CR_ACT && SecAddr == SA_CR) || (SecSi && SecAddr == SA_SecSi && Addr > 8'hFF)) SYNCREAD = 1; else BURST_TR = 1; end end SERS_SUS: begin if (falling_edge_BURST) begin if (SecAddr == SA_ERS || (STAT_ACT && SecAddr == SA_SR)) SYNCREAD =1; else BURST_TR = 1; end end PGM: begin if (falling_edge_BURST) begin if (BankID == BA_PGM || (ESP_ACT && SecAddr == SA_ERS) || (STAT_ACT && SecAddr == SA_SR)) SYNCREAD = 1; else BURST_TR = 1; end end PGM_SL: begin if (falling_edge_BURST) begin if (BankID == BA_PGM || (ESP_ACT && SecAddr == SA_ERS) || (STAT_ACT && SecAddr == SA_SR)) SYNCREAD = 1; else BURST_TR = 1; end end PGM_SUS: begin if (falling_edge_BURST) begin if (BuffPageAddr == PA_PGM || (ESP_ACT && SecAddr == SA_ERS) || (LOCK_ACT && SecAddr == SA_SSR) || (CR_ACT && SecAddr == SA_CR) || (SecSi && SecAddr == SA_SecSi && Addr > 8'hFF) || (STAT_ACT && SecAddr == SA_SR)) 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, rising_edge_CEDONE, ER_FLAG, rising_edge_BCDONE, falling_edge_AVDNeg, falling_edge_RST, falling_edge_READ, rising_edge_CENeg, rising_edge_OENeg, rising_edge_PDONE, rising_edge_START_out, rising_edge_CLKMerge, falling_edge_OENeg, falling_edge_ReadINIT) begin : Functional if (falling_edge_WRITE) begin Data = D_tmp; DataLo = D_tmp % 12'h100; AddrCom = Addr % 16'h1000; end oe = falling_edge_READ; if (falling_edge_RST && ~RESETNeg) begin ESP_ACT = 0; PGM_ACT = 0; LOCK_ACT = 0; SecSi = 0; ConfReg0 = 16'b1101111101001000; START_in = 0; BCDONE = 1; CEDONE = 1; STAT_ACT = 0; Status[7:0] = 8'b10000000; end if (falling_edge_AVDNeg) RDY_temp = 1; if (falling_edge_ReadINIT) begin INITIAL = 1; DelayCycSwitch = 0; BurstAddr = Addr; BurstSec = SecAddr; if (ConfReg0[2:0] == 2) BurstLength = 8; else if (ConfReg0[2:0] == 3) BurstLength = 16; else BurstLength = 0; RDCnt = BurstLength; WS_Initial = 13; if ((ConfReg0[14:11] < 11) && (ConfReg0[14:11] > 0)) WS_Initial = ConfReg0[14: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 >= 10) WS_Boundary = 2; else 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 == ID_CFI_ENTRY && BurstSec == SA_ID_CFI) ReadTarget = ID_CFI_T; else if (SecSi && BurstSec == SA_SecSi) ReadTarget = SS_T; else ReadTarget = Mem_T; end if (reseted) begin case (current_state) IDLE_RST: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h555 && DataLo == 16'h80) begin SA_ERS = SecAddr; BA_ERS = BankID; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h40) begin SA_SSR = SecAddr; LOCK_ACT = 1; STAT_ACT = 0; end else if ((AddrCom == 16'h555 && DataLo == 16'h88)) begin SA_SecSi = SecAddr; SecSi = 1; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'hD0) begin SA_CR = SecAddr; CR_ACT = 1; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h25) begin SA_PGM = SecAddr; BA_PGM = BankID; STAT_ACT = 0; end else if ((AddrCom % 16'h100 == 16'h55) && ((DataLo == 16'h98) || (DataLo == 16'h90)) && (BankID == 0)) begin SA_ID_CFI = SecAddr; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else if (AddrCom == 16'h555 && DataLo == 16'h71) begin Status[7:0] = 8'b10000000; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h33) begin SA_BC = SecAddr; BA_BC = BankID; BCDONE = 0; BCDONE <= #(tdevice_BCHECK) 1; Status[7] = 0; STAT_ACT = 0; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin Status[0] = 0; Dout_zd = Status; STAT_ACT = 0; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end ERASE_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h2AA && DataLo == 16'h10) begin if (SecAddr == SA_ERS && (SL_REG == 0 || SL_REG == -2) && VPP != 0 && ~LockRangeDone) begin CEDONE = 0; CEDONE <= #((SecNum-3)*tdevice_SEO64_ts + 4*tdevice_SEO16_ts) 1; Status[7] = 0; Status[5] = 0; Status[1] = 0; ER_FLAG = 0; end else begin Status[5] = 1; if (SecAddr == SA_ERS) Status[1] = 1; else Status[1] = 0; end end else if (AddrCom == 16'h2AA && DataLo== 16'h30) begin if (SecAddr == SA_ERS && VPP != 0 && (SecAddr == SL_REG || SL_REG == -2)) begin ESTART = 1; ESTART <= #1 0; Status[7] = 0; Status[5] = 0; Status[1] = 0; ER_FLAG = 0; end else begin Status[5] = 1; if (SecAddr == SA_ERS) Status[1] = 1; else Status[1] = 0; end end else if ((DataLo % 8'h10) == 8'hC) begin end else Status[5] = 1; end if (oe) begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end SL_ENTRY: begin if (oe) begin if ((ESP_ACT && SecAddr == SA_ERS) || (PGM_ACT && BuffPageAddr == PA_PGM)) Dout_zd = 16'b0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end SSR_LOCK_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h555 && DataLo == 16'h25 && SecAddr == SA_SSR) begin SA_PGM = SecAddr; BA_PGM = BankID; end else if (DataLo == 8'hF0) LOCK_ACT = 0; end if (oe) begin if (SecAddr == SA_SSR) Dout_zd = SSR_LOCK_REG; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end SecSi_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h555 && DataLo == 16'h25 && SecAddr == SA_SecSi) begin SA_PGM = SecAddr; BA_PGM = BankID; end else if (DataLo == 8'hF0) SecSi = 0; end if (oe) begin if (SecAddr == SA_SecSi) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end CR_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h555 && DataLo == 16'h25 && SecAddr == SA_CR) begin SA_PGM = SecAddr; BA_PGM = BankID; end else if (DataLo == 16'hF0) begin CR_ACT = 0; end end if (oe) begin if (SecAddr == SA_CR) begin if (Addr % 16'h100 == 0) Dout_zd = ConfReg0; else Dout_zd = 16'b0; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end W2B_ENTRY: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h2AA) begin if (SecAddr == SA_PGM && (((SecAddr == SL_REG || SL_REG == -2) && VPP != 0) || (SecSi && VPP != 0) || LOCK_ACT || CR_ACT) && !(SecSi && SSR_LOCK_REG[0] == 0) && !(LOCK_ACT && DataLo>0) && !(CR_ACT && DataLo>0) && !(ESP_ACT && SecAddr == SA_ERS)) begin WC = DataLo % (WrBuffLength+1); WrBuffCnt = DataLo % (WrBuffLength+1); end else begin Status[4] = 1; if ((SecAddr == SA_PGM) && ~LOCK_ACT && ~CR_ACT && !(ESP_ACT && SecAddr == SA_ERS)) Status[1] = 1; else Status[1] = 0; end end else if ((DataLo % 8'h10) == 8'hC) begin end else Status[4] = 1; end if (oe) begin if (ESP_ACT && SecAddr == SA_ERS) Dout_zd = 16'b0; else if (LOCK_ACT && SecAddr == SA_SSR) Dout_zd = SSR_LOCK_REG; else if (CR_ACT && SecAddr == SA_CR) begin if ((Addr % 12'h100) == 0) Dout_zd = ConfReg0; else Dout_zd = 16'b0; end else if (SecSi && SecAddr == SA_SecSi) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end ID_CFI_ENTRY: begin if (oe) begin if (SecAddr == SA_ID_CFI) begin tmpaddr = ReturnAddr(Addr,SecAddr); READMEM(tmpaddr,SecAddr,ID_CFI_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end BC_ENTRY: begin if (rising_edge_BCDONE) begin Status[7] = 1; Status[5] = 0; if (SA_BC <= 3 && (tmp_char=="1")) begin for (j=SA_BC*(SecSize16+1)+sgsaB[0]; j<= SA_BC*(SecSize16+1)+sgsaB[0]+SecSize16; j=j+1) begin if (Mem[j] != MaxData) Status[5] = 1; end end else if (tmp_char == "1") begin for (j= (SA_BC-4)*(SecSize64+1) +sgsaB[1]; j<=(SA_BC-4)*(SecSize64+1) +sgsaB[1]+SecSize64; j=j+1) begin if (Mem[j] != MaxData) Status[5] = 1; end end else if (SA_BC < (SecNum-3) && (tmp_char == "0")) begin for (j=SA_BC*(SecSize64+1)+sgsaT[0]; j<= SA_BC*(SecSize64+1)+sgsaT[0]+SecSize64; j=j+1) begin if (Mem[j] != MaxData) Status[5] = 1; end end else begin i = 0; for (j= (SA_BC- (SecNum-3))*(SecSize16+1)+sgsaT[1]; j<= (SA_BC - (SecNum-3))*(SecSize16+1) + sgsaT[1] + SecSize16; j=j+1) begin if (Mem[j] != MaxData) begin Status[5] = 1; i = i + 1; end end end STAT_ACT = 0; end if (falling_edge_WRITE) begin if (AddrCom== 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin if (BankID == BA_BC) Status[0] = 0; else Status[0] = 1; Dout_zd = Status; STAT_ACT = 0; end else Dout_zd = 16'bx; end end CERS: begin if (~ER_FLAG) begin ER_FLAG = 1; for (i=0; i<= MemSize; i=i+1) Mem[i] = -1; end if (rising_edge_CEDONE) begin for (i=0; i<= MemSize; i=i+1) Mem[i] = MaxData; Status[7] = 1; STAT_ACT = 0; end if (falling_edge_WRITE) begin if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin Status[0] = 0; Dout_zd = Status; STAT_ACT = 0; end else Dout_zd = 16'b0; end end SERS: begin if (~ER_FLAG) begin ER_FLAG = 1; 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 if (rising_edge_EDONE) 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 Status[7] = 1; STAT_ACT = 0; end if (falling_edge_WRITE) begin if (DataLo == 16'hB0) begin ESUSP = 1; ESUSP <= #1 0; START_in = 1; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin if (BankID == BA_ERS) Status[0] = 0; else Status[0] = 1; Dout_zd = Status; STAT_ACT = 0; end else if (BankID == BA_ERS) Dout_zd = 16'b0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end SL_Change: begin if (falling_edge_WRITE) begin if (DataLo == 16'h60 && (Addr % 16'h80)/16'h40 == 0 && (SecAddr == SL_REG || SL_REG == -2)) SL_REG = -1; else if (DataLo == 16'h60 && (Addr % 16'h80)/16'h40 == 1 && SL_REG == -1 && (SecAddr < SLA_Lo || SecAddr > SLA_Hi)) SL_REG = SecAddr; else if (DataLo == 16'h61 && ~LockRangeDone) begin LockRange = 1; SLA_temp = SecAddr; A6Lock = ((Addr % 16'h80)/16'h40 == 0); end else if (DataLo == 16'h61) LockRange = 0; end if (oe) begin if ((ESP_ACT && SecAddr == SA_ERS) || (PGM_ACT && BuffPageAddr == PA_PGM)) Dout_zd = 16'h0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end W2B_WC: begin if (falling_edge_WRITE) begin if (SecAddr == SA_PGM && !(SecSi && (ReturnAddr(Addr, SA_SecSi) < 128 || ReturnAddr(Addr,SA_SecSi) > 255)) && !(LOCK_ACT && ((AddrCom % 12'h100) != 0)) && !(CR_ACT && ((AddrCom % 12'h100) > 0)) && WC == 0) begin PrevAddr <= #1 Addr; WrBuffAddr[0] = Addr; WrBuffData[0] = Data; PA_PGM = BuffPageAddr; end else if (SecAddr == SA_PGM && !(SecSi && (ReturnAddr(Addr,SA_SecSi) < 128 || ReturnAddr(Addr,SA_SecSi) > 255)) && !((Addr+WC) / (WrBuffLength+1)> Addr / (WrBuffLength+1)) && ~LOCK_ACT && ~CR_ACT) begin PrevAddr <= #1 Addr; WrBuffAddr[WC] = Addr; WrBuffData[WC] = Data; WC = WC -1; PA_PGM = BuffPageAddr; end else if ((DataLo % 8'h10) == 8'hC) begin end else Status[4] = 1; end if (oe) begin if (ESP_ACT && SecAddr == SA_ERS) Dout_zd = 16'b0; else if (LOCK_ACT && SecAddr == SA_SSR) Dout_zd = SSR_LOCK_REG; else if (CR_ACT && SecAddr == SA_CR) begin if (Addr % 16'h100 == 0) Dout_zd = ConfReg0; else Dout_zd = 16'b0; end else if (SecSi && SecAddr == SA_SecSi) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end SERS_SL: begin if (rising_edge_START_out) begin START_in = 0; ESP_ACT = 1; Status[7] = 1; Status[6] = 1; STAT_ACT = 0; end if (falling_edge_WRITE) begin if (AddrCom== 16'h555 && DataLo== 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin if (BankID == BA_ERS) Status[0] = 0; else Status[0] = 1; Dout_zd = Status; STAT_ACT = 0; end else if (BankID == BA_ERS) Dout_zd = 16'b0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end LOCK_RANGE: begin if (falling_edge_WRITE) begin if (DataLo == 16'h61 && LockRange && (SecAddr >= SLA_temp) && A6Lock && (Addr % 8'h80)/8'h40 == 0) begin LockRangeDone = 1; SLA_Lo = SLA_temp; SLA_Hi = SecAddr; if (SLA_Lo <= 3 && tmp_char == "1") SLA_Lo = 0; if (SLA_Hi < 3 && tmp_char == "1") SLA_Hi = 3; if (SLA_Lo > (SecNum-3) && tmp_char == "0") SLA_Lo = SecNum-3; if (SLA_Hi >= (SecNum-3) && tmp_char == "0") SLA_Hi = SecNum; if (SL_REG >= SLA_Lo && SL_REG <= SLA_Hi) SL_REG = -1; end end if (oe) begin if ((ESP_ACT && SecAddr == SA_ERS) || (PGM_ACT && BuffPageAddr == PA_PGM)) Dout_zd = 16'b0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end W2BUF_PG: begin if (falling_edge_WRITE) begin if (Addr == PrevAddr + 1) begin WrBuffAddr[WC] = Addr; WrBuffData[WC] = Data; PrevAddr <= #1 Addr; if (WC > 0) WC = WC - 1; end else Status[4] = 1; end if (oe) begin if (ESP_ACT && SecAddr == SA_ERS) Dout_zd = 16'b0; else if (SecSi && SecAddr == SA_SecSi) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end WB_LOADED: begin if (falling_edge_WRITE) begin if (AddrCom == 12'h555 && DataLo == 8'h29 && ((WrBuffAddr[WrBuffCnt]/32) == (WrBuffAddr[0]/32)) && SecAddr == SA_PGM && CR_ACT) begin ConfReg0 = WrBuffData[0]; end else if (AddrCom == 12'h555 && DataLo == 8'h29 && ((WrBuffAddr[WrBuffCnt]/32) == (WrBuffAddr[0]/32)) && SecAddr == SA_PGM && ~CR_ACT) begin PSTART = 1; PSTART <= #1 0; Status[7] = 0; Status[4] = 0; PR_FLAG = 0; end else if ((DataLo % 8'h10) == 8'hC) begin end else Status[4] = 1; end if (oe) begin if (ESP_ACT && SecAddr == SA_ERS) Dout_zd = 16'b0; else if (LOCK_ACT && SecAddr == SA_SSR) Dout_zd = SSR_LOCK_REG; else if (CR_ACT && SecAddr == SA_CR) begin if ((Addr % 12'h100) == 0) Dout_zd = ConfReg0; else Dout_zd = 16'b0; end else if (SecSi && SecAddr == SA_SecSi) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end SERS_SUS: begin if (falling_edge_WRITE) begin if (AddrCom == 16'h000 && DataLo == 16'h30) begin ERES = 1; ERES <= #1 0; ESP_ACT = 0; STAT_ACT = 0; Status[7] = 0; Status[6] = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h25) begin SA_PGM = SecAddr; BA_PGM = BankID; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else if (AddrCom == 16'h555 && DataLo == 16'h71) begin Status[7] = 1; Status[5:3] = 3'b000; Status[1:0] = 2'b00; STAT_ACT = 0; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin Status[0] = 0; Dout_zd = Status; STAT_ACT =0; end else if (SecAddr == SA_ERS) Dout_zd = 16'h0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end PGM: begin if (~PR_FLAG) begin PR_FLAG = 1; if (~LOCK_ACT && ~CR_ACT) begin for (i=WrBuffCnt; i>=0; i=i-1) begin new_int = WrBuffData[i]; old_int = -1; if (SecSi == 1) begin j = ReturnAddr(WrBuffAddr[i],SA_SecSi); old_int = SecSiMem[j]; end else begin j = WrBuffAddr[i]; old_int = Mem[j]; end WrBuffData[i] = -1; if (new_int > -1) begin new_bit = new_int; if (old_int > -1) begin old_bit = old_int; for (j=0; j<= 15; j=j+1) begin if (old_bit[j] == 0) new_bit[j] = 0; end new_int = new_bit; end WrBuffData[i] = new_int; end end end if (LOCK_ACT && SSR_LOCK_REG[0]==1 && (WrBuffData[0] % 2 == 0)) SSR_LOCK_REG[0] = 1'bx; else if (CR_ACT && (WrBuffAddr[0] % 12'h100 == 0)) ConfReg0 = 16'bx; else begin for (i=WrBuffCnt; i>=0; i=i-1) begin if (SecSi == 1) begin j = ReturnAddr(WrBuffAddr[i],SA_SecSi); SecSiMem[j] = -1; end else begin j = WrBuffAddr[i]; Mem[j] = -1; end end end end if (rising_edge_PDONE) begin if (LOCK_ACT && SSR_LOCK_REG[0] === 1'bx) SSR_LOCK_REG[0] = 0; begin for (i= WrBuffCnt; i>=0; i=i-1) begin if (SecSi == 1) begin j = ReturnAddr(WrBuffAddr[i],SA_SecSi); SecSiMem[j] = WrBuffData[i]; end else begin tmpaddr = WrBuffAddr[i]; tmpdata = WrBuffData[i]; Mem[tmpaddr] = tmpdata; end WrBuffData[i] = -1; end end Status[7] = 1; STAT_ACT = 0; end if (falling_edge_WRITE) begin if (DataLo == 16'h51) begin PSUSP = 1; #1 PSUSP = 0; START_in = 1; STAT_ACT = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin if (BankID == BA_PGM) Status[0] = 0; else Status[0] = 1; Dout_zd = Status; STAT_ACT = 0; end else if (BankID == BA_PGM || (ESP_ACT && SecAddr == SA_ERS)) Dout_zd = 16'h0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end PGM_SL: begin if (rising_edge_START_out) begin START_in = 0; PGM_ACT = 1; Status[7] = 1; Status[2] = 1; STAT_ACT = 0; end if (falling_edge_WRITE) begin if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin if (BankID == BA_PGM) Status[0] = 0; else Status[0] = 1; Dout_zd = Status; STAT_ACT = 0; end else if (BankID == BA_PGM || (ESP_ACT && SecAddr == SA_ERS)) Dout_zd = 16'h0; else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; end end end PGM_SUS: begin if (falling_edge_WRITE) begin if (AddrCom == 15'h000 && DataLo == 16'h50) begin PRES = 1; #1 PRES = 0; PGM_ACT = 0; STAT_ACT = 0; Status[7] = 0; Status[2] = 0; end else if (AddrCom == 16'h555 && DataLo == 16'h70 && ~STAT_ACT) begin SA_SR = SecAddr; STAT_ACT = 1; end else if (AddrCom == 16'h555 && DataLo == 16'h71) begin Status[7] = 1; Status[5:3] = 3'b000; Status[1:0] = 2'b00; STAT_ACT = 0; end else STAT_ACT = 0; end if (oe) begin if (STAT_ACT && SecAddr == SA_SR) begin Status[0] = 0; Dout_zd = Status; STAT_ACT = 0; end else if (BuffPageAddr == PA_PGM || (ESP_ACT && SecAddr == SA_ERS) || (LOCK_ACT && SecAddr == SA_SSR) || (CR_ACT && SecAddr == SA_CR)) Dout_zd = 16'h0; else if (SecSi && SecAddr == SA_SecSi) begin READMEM(ReturnAddr(Addr,SecAddr),SecAddr,SS_T); Dout_zd = OutputD; end else begin READMEM(Addr,SecAddr,Mem_T); Dout_zd = OutputD; 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 && BurstStarted == 1) 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 (WS_Boundary > 0) begin RDY_temp = 0; BoundarySwitch = 1; end else begin 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 end else BoundarySwitch = 3; end else if (BoundarySwitch == 1) 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; 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 || (falling_edge_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'h0012; CFIMem[35] = 16'h0003; CFIMem[36] = 16'h0003; CFIMem[37] = 16'h0003; CFIMem[38] = 16'h0003; // Device Geometry Definition CFIMem[39] = 16'h0019; 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'h00FE; else if (tmp_char == "1") CFIMem[45] = 16'h0003; CFIMem[46] = 16'h0000; if (tmp_char == "0") CFIMem[47] = 16'h0000; else if (tmp_char == "1") CFIMem[47] = 16'h0080; if (tmp_char == "0") CFIMem[48] = 16'h0002; 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'h00FE; CFIMem[50] = 16'h0000; if (tmp_char == "0") CFIMem[51] = 16'h0080; 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'h0002; // 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'h0009; CFIMem[74] = 16'h00E0; 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'h0007; CFIMem[83] = 16'h000E; CFIMem[84] = 16'h000E; CFIMem[85] = 16'h0008; CFIMem[86] = 16'h0008; CFIMem[87] = 16'h0008; 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; CFIMem[91] = 16'h0020; CFIMem[92] = 16'h0020; CFIMem[93] = 16'h0020; CFIMem[94] = 16'h0020; if (tmp_char == "0") CFIMem[95] = 16'h0023; else if (tmp_char == "1") CFIMem[95] = 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 ID_CFI_T: begin if (Address >= 16'h10 && Address <= 16'h67) ReadData = CFIMem[Address]; else if (Address == 16'h00) ReadData = 16'h0001; else if (Address == 16'h01) ReadData = 16'h007E; else if (Address == 16'h03) ReadData = 16'h0000; else if (Address == 16'h06) ReadData = 16'h0010; else if (Address == 16'h0C) ReadData = 16'h0005; else if (Address == 16'h0E) begin if (tmp_char == "1") ReadData = 16'h0066; else if (tmp_char == "0") ReadData = 16'h0064; end else if (Address == 16'h0F) ReadData = 16'h0001; 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 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, SA_SecSi); if (SecSiMem[m] != -1) DOut_burst = SecSiMem[m]; end ID_CFI_T: begin m = ReturnAddr(BAddr,SA_ID_CFI); if (m >= 16'h10 && m <= 16'h67) DOut_burst = CFIMem[m]; else if (m == 16'h00) DOut_burst = 16'h0001; else if (m == 16'h01) DOut_burst = 16'h007E; else if (m == 16'h03) DOut_burst = 16'h0000; else if (m == 16'h06) DOut_burst = 16'h0010; else if (m == 16'h0C) DOut_burst = 16'h0005; else if (m == 16'h0E) begin if (tmp_char == "1") DOut_burst = 16'h0066; else if (tmp_char == "0") DOut_burst = 16'h0064; end else if (m == 16'h0F) DOut_burst = 16'h0001; 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 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 == 8'hFF) BAddr = BAddr - 255; else BAddr = BAddr +1; end ID_CFI_T: begin if (BAddr % 16'h80 == 16'h67) BAddr = BAddr - 16'h67; 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)); PageCHECK = ReturnBuffPage((BurstAddr+1) % (MemSize+1)); BusyBound = 0; if ((current_state == IDLE_RST && STAT_ACT && SectorCHECK == SA_SR) || (current_state == SL_ENTRY && ((ESP_ACT && SectorCHECK == SA_ERS) || (PGM_ACT && PageCHECK == PA_PGM))) || (current_state == SSR_LOCK_ENTRY && SectorCHECK == SA_SSR) || (current_state == SecSi_ENTRY && SectorCHECK == SA_SecSi) || (current_state == CR_ENTRY && SectorCHECK == SA_CR) || (current_state == W2B_ENTRY && ((ESP_ACT && SectorCHECK == SA_ERS) || (LOCK_ACT && SectorCHECK == SA_SSR) || (CR_ACT && SectorCHECK == SA_CR) || (SecSi && SectorCHECK == SA_SecSi))) || (current_state == ID_CFI_ENTRY && SectorCHECK == SA_ID_CFI) || (current_state == BC_ENTRY && (BankCHECK == BA_BC || (STAT_ACT && SectorCHECK == SA_SR))) || (current_state == SERS && (BankCHECK == BA_ERS || (STAT_ACT && SectorCHECK == SA_SR))) || (current_state == SL_Change && ((ESP_ACT && SectorCHECK == SA_ERS) || (PGM_ACT && PageCHECK == PA_PGM))) || (current_state == W2B_WC && ((ESP_ACT && SectorCHECK == SA_ERS) || (LOCK_ACT && SectorCHECK == SA_SSR) || (CR_ACT && SectorCHECK == SA_CR) || (SecSi && SectorCHECK == SA_SecSi))) || (current_state == SERS_SL && (BankCHECK == BA_ERS || (STAT_ACT && SectorCHECK == SA_SR))) || (current_state == LOCK_RANGE && ((ESP_ACT && SectorCHECK == SA_ERS) || (PGM_ACT && PageCHECK == PA_PGM))) || (current_state == W2BUF_PG && ((ESP_ACT && SectorCHECK == SA_ERS) || (SecSi && SectorCHECK == SA_SecSi))) || (current_state == WB_LOADED && ((ESP_ACT && SectorCHECK == SA_ERS) || (LOCK_ACT && SectorCHECK == SA_SSR) || (CR_ACT && SectorCHECK == SA_CR) || (SecSi && SectorCHECK == SA_SecSi))) || (current_state == SERS_SUS && (SectorCHECK == SA_ERS || (STAT_ACT && SectorCHECK == SA_SR))) || (current_state == PGM && (BankCHECK == BA_PGM || (ESP_ACT && SectorCHECK == SA_ERS) || (STAT_ACT && SectorCHECK == SA_SR))) || (current_state == PGM_SL && (BankCHECK == BA_PGM || (ESP_ACT && SectorCHECK == SA_ERS) || (STAT_ACT && SectorCHECK == SA_SR))) || (current_state == PGM_SUS && (PageCHECK == PA_PGM || (ESP_ACT && SectorCHECK == SA_ERS) || (LOCK_ACT && SectorCHECK == SA_SSR) || (CR_ACT && SectorCHECK == SA_CR) || (SecSi && SectorCHECK == SA_SecSi) || (STAT_ACT && SectorCHECK == SA_SR)))) BusyBound = 1; BusyBound = BusyBound && (ReturnBank(BurstAddr) != BankCHECK || ReturnSectorID(BurstAddr) != SectorCHECK || ReturnBuffPage(BurstAddr) != PageCHECK); 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 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 @(Din) begin Din_event = 1; #1 Din_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 @(posedge BCDONE) begin rising_edge_BCDONE = 1; #1 rising_edge_BCDONE = 0; end always @( negedge WRITE) begin falling_edge_WRITE = 1; #1 falling_edge_WRITE = 0; end always @(posedge CEDONE) begin rising_edge_CEDONE = 1; #1 rising_edge_CEDONE = 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 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 @(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 @(next_state) begin next_state_event = 1; #1 next_state_event = 0; end always @(negedge ReadINIT) begin falling_edge_ReadINIT = 1; #1 falling_edge_ReadINIT = 0; end reg BuffInOE_ASYN, BuffInOE_SYN, BuffInCE, BuffInADDRIN; wire BuffOutOE_ASYN, BuffOutOE_SYN, BuffOutCE, BuffOutADDRIN; BUFFER BUFOE_ASYN (BuffOutOE_ASYN , BuffInOE_ASYN); BUFFER BUFOE_SYN (BuffOutOE_SYN , BuffInOE_SYN); BUFFER BUFCE (BuffOutCE , BuffInCE); BUFFER BUFADDRIN (BuffOutADDRIN , BuffInADDRIN); initial begin BuffInOE_ASYN = 1'b1; BuffInOE_SYN = 1'b1; BuffInCE = 1'b1; BuffInADDRIN = 1'b1; end always @(posedge BuffOutOE_ASYN) begin OEDQ_01_ASYN = $time; end always @(posedge BuffOutOE_SYN) begin OEDQ_01_SYN = $time; end always @(posedge BuffOutCE) begin CEDQ_01 = $time; end always @(posedge BuffOutADDRIN) begin ADDRDQIN_01 = $time; end endmodule module BUFFER (OUT,IN); input IN; output OUT; buf (OUT, IN); endmodule