⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tb.v

📁 nand flash 仿真模型,支持ONFI 2.0
💻 V
📖 第 1 页 / 共 4 页
字号:
        Ale = 0;
        //Determine how long to wait after the last command latch before toggling Re_n
        //  tCCS is required during a column address change
        //  not all designs have tCCS defined, so tWHR would be the default in that case
        tCCS_cache  = (tCCS_cache_min > tWHR_cache_min) ? tCCS_cache_min : tWHR_cache_min;
        tCCS        = (tCCS_min > tWHR_min)             ? tCCS_min       : tWHR_min;
            
        //if last We_n posedge is recent, need to wait to avoid timing violation
        if (cache_mode) begin
            if (($realtime - tm_wen_pos) < tCCS_cache) begin
                #(tCCS_cache - ($realtime - tm_wen_pos));
            end
        end else begin
            if (($realtime - tm_wen_pos) < tCCS) begin
                #(tCCS - ($realtime - tm_wen_pos));
            end
        end
        if (($realtime - tm_rbn_pos) < tRR_min) begin
            #(tRR_min - ($realtime - tm_rbn_pos));
        end
        if (($realtime - tm_cen_neg) < tCLR_min) begin
            #(tCLR_min - ($realtime - tm_cen_neg));
        end        
        Re_n <= 0;
        if (enable_rd_verify) begin //if using this testbench to check the data, enable_rd_verify will be active
            if (cache_mode) begin
                if (tm_cen_neg + tCEA_cache_max > $realtime) begin
                    rd_verify <= #(tCEA_cache_max +1) 1'b1;
                end else begin
                    rd_verify <= #(tREA_cache_max +1) 1'b1;
                end
            end else begin
                if (tm_cen_neg + tCEA_max > $realtime) begin
                    rd_verify <= #(tCEA_max +1) 1'b1;
                end else begin
                    rd_verify <= #(tREA_max +1) 1'b1;
                end
            end  
        end
        #(tRP);
        Re_n <= 1;
        #(tRC-tRP);
    end
    endtask

    //pulse Re_n to latch read data
    //special timing for Programmable DriveStrength
    task latch_read_pio;
    parameter trl=tRPIO_min;
    parameter trh=tRPIO_min;
    begin
        Cle = 0;
        Ale = 0;
          Re_n <= 0;
        if (enable_rd_verify) begin //if using this testbench to check the data, enable_rd_verify will be active
            rd_verify <= #(tREAIO_max +1) 1'b1;
        end  
        #(trl);
          Re_n <= 1;
        #(trh);
    end
    endtask


    task latch_address;
    input [7 : 0] addr_in;

    reg we_setup;
    reg ale_setup;
    reg cle_setup;
    reg ce_setup;
    reg io_setup;
    reg ale_hold;
    reg we_hold;
    reg io_hold;
    begin
        if (sync_mode) begin
        end else begin
            //these allow us to keep track of how far from the previous
            // signal edge we are in real time.  No need to delay the 
            // We_n transitions of timing checks are already met
            we_setup = 0;
            ale_setup = 0;
            cle_setup = 0;
            ce_setup = 0;
            io_setup = 0;
        
            ale_hold = 0;
            we_hold = 0;
            io_hold = 0;
            
            Ale = 1'b1;
            Io[7:0] = addr_in;
`ifdef x16
                Io[15:8] = 8'b0;
`endif
            
            if (($realtime - tm_wen_pos) < tWH) begin
                #($realtime - tm_wen_pos);
            end
            We_n = 1'b0;
        
            //Check Cle        
            if (cache_mode) begin
                if (($realtime - tm_cle_pos) < tCLS_cache_min) begin 
                    cle_setup <= #(tCLS_cache_min - ($realtime - tm_cle_neg)) 1'b1;
                end else begin
                    cle_setup = 1'b1;
                end
            end else begin
                if (($realtime - tm_cle_pos) < tCLS_min) begin 
                    cle_setup <= #(tCLS_min - ($realtime - tm_cle_neg)) 1'b1;
                end else begin
                    cle_setup = 1'b1;
                end
            end
            //Check Ce_n
            if (cache_mode) begin
                if (($realtime - tm_cen_neg) < tCS_cache_min) begin 
                    ce_setup <= #(tCS_cache_min - ($realtime - tm_cen_neg)) 1'b1;
                end else begin
                    ce_setup = 1'b1;
                end
            end else begin
                if (($realtime - tm_cen_neg) < tCS_min) begin 
                    ce_setup <= #(tCS_min - ($realtime - tm_cen_neg)) 1'b1;
                end else begin
                    ce_setup = 1'b1;
                end
            end
            //Check Cle setup
            if (cache_mode) begin
                ale_setup <= #tALS_cache_min 1'b1;
                io_setup  <= #tDS_cache_min 1'b1;
            end else begin
                ale_setup <= #tALS_min 1'b1;
                io_setup  <= #tDS_min 1'b1;
            end
            we_setup <= #tWP 1'b1;
    
            //wait for all setup times to be met
            wait (we_setup && ale_setup && cle_setup && ce_setup && io_setup);
            We_n = 1;
            
            if (cache_mode) begin
                ale_hold <= #tALH_cache_min 1'b1;
                io_hold <= #tDH_cache_min 1'b1;
            end else begin
                ale_hold <= #tALH_min 1'b1;
                io_hold <= #tDH_min 1'b1;
            end
            //user defined or default value
            we_hold <= #tWH 1'b1;
              
            //wait for hold times to be met
            wait (we_hold && io_hold && ale_hold);
            Ale = 0;
            Io = {DQ_BITS{1'bz}};
        end
    end
    endtask



    //latches the command on IO on posedge We_n
    task latch_command;
    input [DQ_BITS - 1 : 0] data_in;
    reg we_setup;
    reg ale_setup;
    reg cle_setup;
    reg ce_setup;
    reg io_setup;
    reg trhw_setup;
    reg cle_hold;
    reg ce_hold;
    reg ale_hold;
    reg we_hold;
    reg io_hold;
    real delay;
    begin
        if (sync_mode) begin
        end else begin
            //these allow us to keep track of how far from the previous
            // signal edge we are in real time.  No need to delay the 
            // We_n transitions of timing checks are already met
            we_setup = 0;
            ale_setup = 0;
            cle_setup = 0;
            ce_setup = 0;
            io_setup = 0;
            trhw_setup = 0;

            cle_hold = 0;
            ce_hold = 0;
            ale_hold = 0;
            we_hold = 0;
            io_hold = 0;

            //If pulsing Re_n to read data was the 
            //last op, wait for the x's to clear as 
            //the device may or may not still be driving
            //data during the 'x' time.  Need to wait for 
            //the Io bus to be high impedance.
            wait (IO !== {DQ_BITS{1'bx}});
            Cle = 1'b1;
            Io = data_in;

            //if we just finished a read, wait for tRHW to be met
            if (($realtime - tm_ren_pos) < tRHW_min) begin 
                trhw_setup <= #(tRHW_min - ($realtime - tm_ren_pos)) 1'b1;
                We_n <= #(tRHW_min - ($realtime - tm_ren_pos)) 1'b0;
                we_setup <= #(tRHW_min - ($realtime-tm_ren_pos) + tWP) 1'b1;
            end else begin
                trhw_setup = 1'b1;
                We_n = 1'b0;
                we_setup <= #tWP 1'b1;
            end
            //Check Ale        
            if (cache_mode) begin
                if (($realtime - tm_ale_neg) < tALS_cache_min) begin 
                    ale_setup <= #(tALS_cache_min - ($realtime - tm_ale_neg)) 1'b1;
                end else begin
                    ale_setup = 1'b1;
                end
            end else begin
                if (($realtime - tm_ale_neg) < tALS_min) begin 
                    ale_setup <= #(tALS_min - ($realtime - tm_ale_neg)) 1'b1;
                end else begin
                    ale_setup = 1'b1;
                end
            end
            //Check Cle setup
            if (cache_mode) begin
                cle_setup <= #tCLS_cache_min 1'b1;
                io_setup  <= #tDS_cache_min 1'b1;
            end else begin
                cle_setup <= #tCLS_min 1'b1;
                io_setup  <= #tDS_min 1'b1;
            end
        
            //Check Ce_n
            #1;
            if (cache_mode) begin
                if ((Ce_n === 1'b0) && (($realtime - tm_cen_neg) < tCS_cache_min)) begin 
                    ce_setup <= #(tCS_cache_min - ($realtime - tm_cen_neg)) 1'b1;
                end else if ((Ce2_n === 1'b0) && (($realtime - tm_ce2n_neg) < tCS_cache_min)) begin
                    ce_setup <= #(tCS_cache_min - ($realtime - tm_ce2n_neg)) 1'b1;
                end else begin
                    ce_setup = 1'b1;
                end
            end else begin
                if ((Ce_n === 1'b0) && (($realtime - tm_cen_neg) < tCS_min)) begin 
                    ce_setup <= #(tCS_min - ($realtime - tm_cen_neg)) 1'b1;
                end else if ((Ce2_n === 1'b0) && (($realtime - tm_ce2n_neg) < tCS_min)) begin
                    ce_setup <= #(tCS_min - ($realtime - tm_ce2n_neg)) 1'b1;
                end else begin
                    ce_setup = 1'b1;
                end
            end
        
            //wait for all setup times to be met
            wait (we_setup && ale_setup && cle_setup && ce_setup && io_setup && trhw_setup);
            We_n = 1;
        
            if (cache_mode) begin
                cle_hold <= #tCLH_cache_min 1'b1;
                ale_hold <= #tALH_cache_min 1'b1;
                io_hold <= #tDH_cache_min 1'b1;
            end else begin
                cle_hold <= #tCLH_min 1'b1;
                ale_hold <= #tALH_min 1'b1;
                io_hold <= #tDH_min 1'b1;
            end
            //user defined or default value
            we_hold <= #tWH 1'b1;
          
            //wait for hold times to be met
            wait (we_hold && io_hold && ale_hold && cle_hold);
            Cle = 0;
            if ((Io[7:0] !== 8'h70) && (Io[7:0] !== 8'h78)) lastCmd = Io;
            Io = {DQ_BITS{1'bz}};
        end
    end
    endtask


    task latch_command_pio;
    input [DQ_BITS - 1 : 0] data_in;
    begin
        #(tRHW_min + tCLSIO_min);  
         We_n = 0;
        Ale = 0;
        Cle = 1;
        Io = data_in;
        #tWPIO_min;     
        We_n = 1;
        #(tWHIO_min + tCLHIO_min); 
        Cle = 0;
        Io = {DQ_BITS{1'bz}};
    end
    endtask


    task latch_data_sync;
        input [DQ_BITS -1: 0] data0_in;
        input [DQ_BITS -1: 0] data1_in;
    begin
    end
    endtask
    
    //pulse we to latch write data

    task latch_data_async;
        input [DQ_BITS - 1 : 0] data_in;
    begin
        We_n = 0;
        Io = data_in;
        //tWP is almost always > tDS_min
        //tWH is almost always > tDH_min
        if (tWP > tDS_min) begin
            #tWP;
        end else begin
            #tDS_min;
        end
        //wait for tCCS if this was a column change
        if ((($realtime - tm_wen_pos) < tCCS_min) && ((lastCmd === 8'h85) || (lastCmd === 8'hE0))) begin
            #(tCCS_min - ($realtime - tm_wen_pos));
        end
        We_n = 1;
        if (tWH > tDH_min) begin
            #tWH;
        end else begin
            #tDH_min;
        end
        Io = {DQ_BITS{1'bz}};
    end
    endtask
    

    task latch_data_pio;
        input [DQ_BITS - 1 : 0] data_in;
    begin
        #(tWPIO_min - (tWHIO_min - tDHIO_min));
      We_n = 0;
        Ale = 0;
        #(tWPIO_min-tDSIO_min);  
        Ale = 0;
        Io = data_in;
        #tWPIO_min;       // 10 ns
      We_n = 1;
        #(tWCIO_min - tWPIO_min);
        //#tDH_min;
        Io = {DQ_BITS{1'bz}};
        #(tWHIO_min-tDHIO_min);
    end
    endtask

    // Status Read (70h)
    task status_read;
    begin
        $display ("%m at time %t", $realtime);
          latch_command (8'h70);
        #tWHR_min;
    end
    endtask

    //No Op
    task nop;
    input trc;
    real trc;
    begin
        #trc;
    end
    endtask

    task go_idle;
    begin
    end
    endtask
    
    // 0 = regular lock, 1 = locktight
    task lock_block;
    input locktight;
    begin
        if (locktight === 1'b1) begin
            latch_command(8'h2C);
        end else begin
            latch_command(8'h2A);
        end
    end
    endtask

    task get_drivestrength;
    begin
        // Decode Command
        latch_command_pio (8'hB8);
        #tWHRIO_min;
    end
    endtask

    task set_drivestrength;
        input [7 : 0] drivestrength;
    begin
        // Decode Command

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -