// ******************************************************************************************************* // ** ** // ** AS6C6416_55_model.v - 64M Bits(4Mx16/8Mx8 Switchable) LOW POWER CMOS SRAM ** // ** ** // ******************************************************************************************************* // ** This information is distributed under license from Alliance Memory Inc. ** // ** COPYRIGHT (c) 2017 Alliance Memory Inc. ** // ** ALL RIGHTS RESERVED ** // ******************************************************************************************************* // ** ** // ** Revision : 0.2 ** // ** Modified Date : 06/01/2017 ** // ** DataSheet file version : AS6C6416-V1.2.pdf ** // ** Revision History: ** // ** ** // ** 06/01/2017: V0.1: Initial design ** // ** 12/25/2017: V0.2: Modify BYTE# fixed Low, Read state ** // ** ** // ******************************************************************************************************* `timescale 1ns/10ps module as6c6416_55 (A, DQ, CEn, CE2, OEn, WEn, LBn, UBn ,BYTEn); // ******************************************************************************************************* // ** Device define ** // ******************************************************************************************************* parameter DataWidth = 16; parameter MemSize = 4194304; parameter AddrWidth = 22; // ******************************************************************************************************* // ** TIMING SPEC ** // ******************************************************************************************************* parameter delta = 0.01; // Delta for stimulus // parameter for check timing parameter tRC = 55; // min. Read Cycle Time parameter tAA = 55; // max. Address Access Time parameter tACE = 55; // max. Chip Enable Access Time parameter tOE = 30; // max. Output Enable Access Time parameter tCLZ = 10; // min. Chip Enable to Output in Low-Z parameter tOLZ = 5; // min. Output Enable to Output in Low-Z parameter tCHZ = 20; // max. Chip Disable to Output in High-Z parameter tOHZ = 20; // max. Output Disable to Output in High-Z1 parameter tOH = 10; // min. Output Hold from Address Change parameter tBA = 55; // max. LBn,UBn Access Time parameter tBHZ = 20; // max. LBn,UBn to High-Z Output parameter tBLZ = 10; // min. LBn,UBn to Low-Z Output parameter tWC = 55; // min. Write Cycle Time parameter tAW = 50; // min. Address Valid to End of Write parameter tCW = 50; // min. Chip Enable to End of Write parameter tAS = 0; // min. Address Set-up time parameter tWP = 45; // min. Write Pulse Width parameter tWR = 0; // min. Write Recovery Time parameter tDW = 25; // min. Data to Write Time Overlap parameter tDH = 0; // min. Data Hold from End of Write Time parameter tOW = 5; // min. Output Active from End of Write parameter tWHZ = 20; // max. Write to Ouput in High-Z parameter tBW = 50; // min. LBn,UBn Valid to End of Write //parameter for stimulus parameter tRC_S = tRC-delta; // min. Read Cycle Time parameter tAA_S = tAA-delta; // max. Address Access Time parameter tACE_S = tACE-delta; // max. Chip Enable Access Time parameter tOE_S = tOE-delta; // max. Output Enable Access Time parameter tCLZ_S = tCLZ-delta; // min. Chip Enable to Output in Low-Z parameter tOLZ_S = tOLZ-delta; // min. Output Enable to Output in Low-Z parameter tCHZ_S = tCHZ-delta; // max. Chip Disable to Output in High-Z parameter tOHZ_S = tOHZ-delta; // max. Output Disable to Output in High-Z parameter tOH_S = tOH-delta; // min. Output Hold from Address Change parameter tBA_S = tBA-delta; // max. LBn,UBn Access Time parameter tBHZ_S = tBHZ-delta; // max. LBn,UBn to High-Z Output parameter tBLZ_S = tBLZ-delta; // min. LBn,UBn to Low-Z Output parameter tWC_S = tWC-delta; // min. Write Cycle Time parameter tAW_S = tAW-delta; // min. Address Valid to End of Write parameter tCW_S = tCW-delta; // min. Chip Enable to End of Write parameter tAS_S = tAS-delta; // min. Address Set-up time parameter tWP_S = tWP-delta; // min. Write Pulse Width parameter tWR_S = tWR-delta; // min. Write Recovery Time parameter tDW_S = tDW-delta; // min. Data to Write Time Overlap parameter tDH_S = tDH-delta; // min. Data Hold from End of Write Time parameter tOW_S = tOW-delta; // min. Output Active from End of Write parameter tWHZ_S = tWHZ-delta; // max. Write to Ouput in High-Z parameter tBW_S = tBW-delta; // min. LBn,UBn Valid to End of Write // ******************************************************************************************************* // ** PIN ** // ******************************************************************************************************* input CEn, CE2, OEn, WEn, LBn, UBn, BYTEn; input [(AddrWidth - 1) : 0] A; //[21:0]A inout [(DataWidth - 1) : 0] DQ; // DQ15/A-1 //---------------------------------------------------------------- reg [(DataWidth - 1) : 0] dout; //[15:0] dout; reg [(DataWidth/2 - 1) : 0] bank0 [0 : MemSize-1]; //[7:0]bank0 [0:4194303] reg [(DataWidth/2 - 1) : 0] bank1 [0 : MemSize-1]; //[7:0]bank1 [0:4194303] wire r_en; wire w_en; wire w_en2; wire ReadLowBusEn,ReadHighBusEn,DataOutEn,DataOutEn_S,UnknowDataOutEn,UnknowDataOutEn_S; wire A_1; // DQ15/A-1 reg rA1,rA2,rA3,rCE,rOE,rLB,rUB,rWE; reg flag_EndOfWrite; wire rA,rReadDataStrobe,wReadCycle_1,wReadCycle_delay; reg rReadCycleHold; wire wReadDataStrobe_WEn,wReadDataStrobe_LBn,wReadDataStrobe_UEn,DataOutValid; // ******************************************************************************************************* // ** Initial ** // ******************************************************************************************************* initial begin rCE <= 1'b0; rOE <= 1'b0; rLB <= 1'b0; rUB <= 1'b0; rWE <= 1'b0; rA1 <= 1'b1; rA2 <= 1'b1; rA3 <= 1'b1; flag_EndOfWrite <= 1'b1; rReadCycleHold <= 1'b0; end assign A_1 = DQ[15]; // ******************************************************************************************************* // ** Read ** // ******************************************************************************************************* always @(posedge DataOutEn_S or negedge wReadDataStrobe_WEn) begin dout[(DataWidth/2 - 1) : 0] = ReadLowBusEn ? (BYTEn ? bank0[A] : (~A_1 ? bank0[A] : bank1[A])) : 8'bz ; dout[(DataWidth - 1) : (DataWidth/2)] = ReadHighBusEn ? (BYTEn ? bank1[A] : 8'bz) : 8'bz ; end always @(A) // Address Toggle inside Chip Enable begin if (~CEn & CE2 & ~(LBn & UBn)) begin rA1 <= 1'b1; // Address toggle to High-Z data output timming #tOH_S rA1 <= 1'b0; end end always @(A) // Address Toggle inside Chip Enable begin if (~CEn & CE2 & ~(LBn & UBn)) begin rA2 <= 1'b0; #tAA_S rA2 <= 1'b1; end end wire wCE, wCE_LZ; reg wCE_tACE, wCE_tCHZ, wCE_tCLZ ; always @(CEn) begin wCE_tACE <= #tACE_S ~CEn; wCE_tCHZ <= #tCHZ_S ~CEn; wCE_tCLZ <= #tCLZ_S ~CEn; end assign wCE = wCE_tACE & wCE_tCHZ; assign wCE_LZ = wCE_tCLZ & ~CEn ; wire wCE2, wCE2_LZ; reg wCE2_tACE, wCE2_tCHZ, wCE2_tCLZ ; always @(CE2) begin wCE2_tACE <= #tACE_S CE2; wCE2_tCHZ <= #tCHZ_S CE2; wCE2_tCLZ <= #tCLZ_S CE2; end assign wCE2 = wCE2_tACE & wCE2_tCHZ; assign wCE2_LZ = wCE2_tCLZ & CE2 ; wire wOE, wOE_LZ; reg wOE_tOE, wOE_tOHZ, wOE_tOLZ ; always @(OEn) begin wOE_tOE <= #tOE_S ~OEn; wOE_tOHZ <= #tOHZ_S ~OEn; wOE_tOLZ <= #tOLZ_S ~OEn; end assign wOE = wOE_tOE & wOE_tOHZ; assign wOE_LZ = wOE_tOLZ & ~(OEn | ~WEn); wire wLB, wLB_LZ; reg wLB_tBA, wLB_tBHZ, wLB_tBLZ ; always @(LBn) begin wLB_tBA <= #tBA_S ~LBn; wLB_tBHZ <= #tBHZ_S ~LBn; wLB_tBLZ <= #tBLZ_S ~LBn; end assign wLB = wLB_tBA & wLB_tBHZ; assign wLB_LZ = wLB_tBLZ & ~LBn; wire wUB, wUB_LZ; reg wUB_tBA, wUB_tBHZ, wUB_tBLZ ; always @(UBn) begin wUB_tBA <= #tBA_S ~UBn; wUB_tBHZ <= #tBHZ_S ~UBn; wUB_tBLZ <= #tBLZ_S ~UBn; end assign wUB = wUB_tBA & wUB_tBHZ; assign wUB_LZ = wUB_tBLZ & ~UBn; reg wWE_tOW, wWE_tWHZ; always @(WEn) begin wWE_tOW <= #tOW_S WEn; wWE_tWHZ <= #tWHZ_S WEn; end reg wWE; always @(WEn) begin if (WEn) wWE <= #tOW_S WEn; else wWE <= #tWHZ_S WEn; end always @(negedge WEn) begin if (wReadCycle_1 & DataOutValid) begin rReadCycleHold <= 1'b1; #tWHZ_S rReadCycleHold <= 1'b0; end end assign #0.01 ReadLowBusEn = (BYTEn & ~LBn) | (~BYTEn & ~LBn); assign #0.01 ReadHighBusEn = BYTEn & ~UBn; assign DataOutValid = ~rA & wCE& wCE2 & wOE & wUB & wLB & wWE; assign DataOutEn = ~rA & wCE & wCE2 & wOE & (wUB | wLB) & (wWE | rReadCycleHold); assign #0.1 wReadDataStrobe_WEn = ~CEn & CE2 & ~OEn & ~WEn; assign #0.1 wReadDataStrobe_LBn = ~CEn & CE2 & ~OEn & ~WEn & ~LBn; assign #0.1 wReadDataStrobe_UEn = ~CEn & CE2 & ~OEn & ~WEn & ~UBn; assign #0.01 DataOutEn_S=DataOutEn; assign #0.01 UnknowDataOutEn_S=UnknowDataOutEn; assign UnknowDataOutEn = (wUB_LZ & wLB_LZ & wOE_LZ & wCE_LZ & wCE2_LZ) & ~DataOutEn & (WEn & wWE_tOW); assign DQ = DataOutEn_S ? dout : (UnknowDataOutEn_S ? 16'bx : 16'bz); assign rA = ~(rA1 | rA2); // ******************************************************************************************************* // ** Write ** // ******************************************************************************************************* reg AddEnable1, AddEnable2 ,rLBC , rUBC; wire AddEnable; reg [15:0] DQ_pathdelay; assign AddEnable = (AddEnable1 ^ AddEnable2); assign w_en = (~WEn) & (~CEn) & CE2 & ((~LBn) | (~UBn)); assign w_en2 = (~WEn) & (~CEn) & CE2 & (~LBn) & (~UBn); always @(DQ) DQ_pathdelay <= #0.1 DQ; initial begin AddEnable1 = 1'b0; AddEnable2 = 1'b0; end always @ (LBn or UBn) begin rLBC <= #0.01 LBn; rUBC <= #0.01 UBn; end always @ (negedge w_en) begin if (BYTEn) begin if (LBn) bank0[A] = rLBC ? bank0[A] : DQ_pathdelay [(DataWidth/2 - 1) : 0]; if (UBn) bank1[A] = rUBC ? bank1[A] : DQ_pathdelay [(DataWidth - 1) : (DataWidth/2)]; bank0[A] = LBn ? bank0[A] : DQ_pathdelay [(DataWidth/2 - 1) : 0]; bank1[A] = UBn ? bank1[A] : DQ_pathdelay [(DataWidth - 1) : (DataWidth/2)]; end else if (~A_1) begin bank0[A] = DQ_pathdelay [(DataWidth/2 - 1) : 0]; end else if (A_1) begin bank1[A] = DQ_pathdelay [(DataWidth/2 - 1) : 0]; end end always @ (negedge w_en2) begin if (BYTEn) begin if (LBn) bank0[A] = rLBC ? bank0[A] : DQ_pathdelay [(DataWidth/2 - 1) : 0]; if (UBn) bank1[A] = rUBC ? bank1[A] : DQ_pathdelay [(DataWidth - 1) : (DataWidth/2)]; bank0[A] = LBn ? bank0[A] : DQ_pathdelay [(DataWidth/2 - 1) : 0]; bank1[A] = UBn ? bank1[A] : DQ_pathdelay [(DataWidth - 1) : (DataWidth/2)]; end else if (~A_1) begin bank0[A] = DQ_pathdelay [(DataWidth/2 - 1) : 0]; end else if (A_1) begin bank1[A] = DQ_pathdelay [(DataWidth/2 - 1) : 0]; end end always @(A) begin if (~CEn & ~WEn ) begin AddEnable1 <= ~AddEnable1; AddEnable2 <= #tAW_S ~AddEnable2; end else begin AddEnable1 <= 1'b0; AddEnable2 <= 1'b0; end end // ******************************************************************************************************* // ** TIMING CHECKS ** // ******************************************************************************************************* //------------- tDW : min. 25 Data to Write Time Overlap : Valid data to End of write (WEn or CEn or LBn or UBn posedge or CE2 nededge) min. time 25ns real tm_DQ_toggle1,tm_DQ_toggle2,tm_DQ_setup, tm_DQ_hold, tm_UB_rising, tm_LB_rising, tm_WE_rising, tm_CEn_rising, tm_CE2_falling, temp1,temp2,temp3; real tm_A_toggle, tm_A_last,flag_A_last; real tm_CEn_falling,tm_CE2_rising; initial begin tm_A_toggle <=0; tm_A_last <=0; tm_DQ_toggle1 <= 0; tm_DQ_toggle2 <= 0; flag_A_last <= 0; end always @(negedge CEn) tm_CEn_falling <= $realtime; always @(posedge CE2) tm_CE2_rising <= $realtime; always @(negedge WEn) flag_EndOfWrite <= 1'b0; always @(DQ) begin tm_DQ_toggle1 <= $realtime; tm_DQ_toggle2 <= tm_DQ_toggle1; end always @(posedge UBn) begin if (($realtime-tm_DQ_toggle1) > 0.1) begin if ((CE2 & ~CEn & ~WEn) && ($realtime - tm_DQ_toggle1 < tDW)) $display("Error: tDW UBn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle1,tDW); end else begin if ((CE2 & ~CEn & ~WEn) && ($realtime - tm_DQ_toggle2 < tDW)) $display("Error: tDW UBn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle2,tDW); end end always @(posedge LBn) begin if (($realtime-tm_DQ_toggle1) > 0.1) begin if ((CE2 & ~CEn & ~WEn) && ($realtime - tm_DQ_toggle1 < tDW)) $display("Error: tDW LBn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle1,tDW); end else begin if ((CE2 & ~CEn & ~WEn) && ($realtime - tm_DQ_toggle2 < tDW)) $display("Error: tDW LBn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle2,tDW); end end always @(posedge WEn) begin if (($realtime-tm_DQ_toggle1) > 0.1) begin if($realtime - tm_DQ_toggle1 < tDW) $display("Error: tDW WEn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle1,tDW); end else begin if($realtime - tm_DQ_toggle2 < tDW) $display("Error: tDW WEn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle2,tDW); end end always @(posedge CEn) begin if (($realtime-tm_DQ_toggle1) > 0.1) begin if ((~WEn) && ($realtime - tm_DQ_toggle1 < tDW)) $display("Error: tDW CEn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle1,tDW); end else begin if ((~WEn) && ($realtime - tm_DQ_toggle2 < tDW)) $display("Error: tDW CEn rising DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle2,tDW); end end always @(negedge CE2) begin if (($realtime-tm_DQ_toggle1) > 0.1) begin if ((~WEn ) && ($realtime - tm_DQ_toggle1 < tDW)) $display("Error: tDW CE2 falling DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle1,tDW); end else begin if ((~WEn ) && ($realtime - tm_DQ_toggle2 < tDW)) $display("Error: tDW CE2 falling DQ setup time violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10, $realtime - tm_DQ_toggle2,tDW); end end //------------- tAS : min. 0 Address Set-up time : Address min. setup time 0ns, before CEn or LBn 0r UBn or WEn negedge or CE2 posedge parameter BusSkew =10; wire [(AddrWidth - 1) : 0] A_glitch,A_delay ; reg rA_glitch; reg rCEnFalling_mask,rCE2Rising_mask,rWEnFalling_mask,rUBnFalling_mask,rLBnFalling_mask; initial begin rA_glitch =1'b0; end assign #0.1 A_delay = A; //----------delay A 0.1ns to generate A transition pulse glitch assign A_glitch = A^A_delay; always @(A_glitch) begin rA_glitch <= 1'b1; #0.1 rA_glitch <= 1'b0; end always @(negedge WEn) begin if (~CEn & CE2) begin #0.2 rWEnFalling_mask <= 1'b1; //--------------- 0.2ns filter out A trans align with CEn falling event #BusSkew rWEnFalling_mask <= 1'b0; end end always @(negedge LBn) begin if (~CEn & CE2 & ~WEn) begin #0.2 rLBnFalling_mask <= 1'b1; //--------------- 0.2ns filter out A trans align with CEn falling event #BusSkew rLBnFalling_mask <= 1'b0; end end always @(negedge UBn) begin if (~CEn & CE2 & ~WEn) begin #0.2 rUBnFalling_mask <= 1'b1; //--------------- 0.2ns filter out A trans align with CEn falling event #BusSkew rUBnFalling_mask <= 1'b0; end end always @(negedge CEn) begin #0.2 rCEnFalling_mask <= 1'b1; //--------------- 0.2ns filter out A trans align with CEn falling event #BusSkew rCEnFalling_mask <= 1'b0; end always @(CE2) begin if (CE2) begin #0.2 rCE2Rising_mask <= 1'b1; //--------------- 0.2ns filter out A trans align with CEn falling event #BusSkew rCE2Rising_mask <= 1'b0; end end always @(rA_glitch) begin if (~CEn & CE2 & ~WEn & rWEnFalling_mask & rA_glitch) $display("Error: tAS WEn falling to Address transition min. time violation at time %t ps", $realtime*10); if (~CEn & CE2 & ~WEn & rUBnFalling_mask & rA_glitch) $display("Error: tAS UBn falling to Address transition min. time violation at time %t ps", $realtime*10); if (~CEn & CE2 & ~WEn & rLBnFalling_mask & rA_glitch) $display("Error: tAS LBn falling to Address transition min. time violation at time %t ps", $realtime*10); if (~CEn & CE2 & ~WEn & rCE2Rising_mask & rA_glitch) $display("Error: tAS CE2 rising to Address transition min. time violation at time %t ps", $realtime*10); if (~CEn & CE2 & ~WEn & rCEnFalling_mask & rA_glitch) $display("Error: tAS CEn falling to Address transition min. time violation at time %t ps", $realtime*10); end //---------------tWR:min. 0: Write Recovery Time before CEn or LBn 0r UBn or WEn posedge or CE2 posedge real tm_tran_tWR; always @(posedge rA_glitch) begin tm_tran_tWR <= $realtime; end always @(posedge WEn) begin if ((~CEn & CE2) && ((BusSkew > $realtime-tm_tran_tWR)&&($realtime-tm_tran_tWR > 0))) $display("Error: tWR violation at WEn rising time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,tm_tran_tWR-$realtime,tWR); end always @(posedge UBn) begin if ((~CEn & CE2 & ~WEn) && ((BusSkew > $realtime-tm_tran_tWR)&&($realtime-tm_tran_tWR > 0))) $display("Error: tWR violation at UBn rising time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,tm_tran_tWR-$realtime,tWR); end always @(posedge LBn) begin if ((~CEn & CE2 & ~WEn) && ((BusSkew > $realtime-tm_tran_tWR)&&($realtime-tm_tran_tWR > 0))) $display("Error: tWR violation at LBn rising time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,tm_tran_tWR-$realtime,tWR); end always @(posedge CEn) begin if ((BusSkew > $realtime-tm_tran_tWR)&&($realtime-tm_tran_tWR > 0)) $display("Error: tWR violation at CEn rising time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,tm_tran_tWR-$realtime,tWR); end always @(negedge CE2) begin if ((BusSkew > $realtime-tm_tran_tWR)&&($realtime-tm_tran_tWR > 0)) $display("Error: tWR violation at CE2 rising time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,tm_tran_tWR-$realtime,tWR); end //---------------tDH min. 0 Data Hold time from End of Write(CEn or WEn or LBn or UBn posedge or CE2 negedge) real tm_tran_tDH; wire [(DataWidth - 1) : 0] DQ_glitch,DQ_delay ; assign #0.1 DQ_delay = DQ; //----------delay A 0.1ns to generate A transition pulse glitch assign DQ_glitch = DQ^DQ_delay; always @(posedge DQ_glitch) begin tm_tran_tDH <= $realtime; end always @(posedge WEn) begin flag_EndOfWrite <= 1'b1; if ((flag_EndOfWrite == 1'b0)&&(BusSkew > $realtime-tm_tran_tDH)&&($realtime-tm_tran_tDH > 0)) $display("Error: tDH WEn rising, tDH violation at time %t ps", $realtime*10); end always @(posedge CEn) begin flag_EndOfWrite <= 1'b1; if ((flag_EndOfWrite == 1'b0)&&(~WEn) && (BusSkew > $realtime-tm_tran_tDH)&&($realtime-tm_tran_tDH > 0)) $display("Error: tDH CEn rising, tDH violation at time %t ps", $realtime*10); end always @(posedge UBn) begin if ((~CEn & CE2 & ~WEn) && (BusSkew > $realtime-tm_tran_tDH)&&($realtime-tm_tran_tDH > 0)) $display("Error: tDH UBn rising, tDH violation at time %t ps", $realtime*10); end always @(posedge LBn) begin if ((~CEn & CE2 & ~WEn) && (BusSkew > $realtime-tm_tran_tDH)&&($realtime-tm_tran_tDH > 0)) $display("Error: tDH LBn rising, tDH violation at time %t ps", $realtime*10); end always @(negedge CE2) begin if ((~WEn) && (BusSkew > $realtime-tm_tran_tDH)&&($realtime-tm_tran_tDH > 0)) $display("Error: tDH CE2 falling, tDH violation at time %t ps", $realtime*10); end //--------------- tRC and tWC : min. tRC=55 Read Cycle Time; min. tWC=55 Write Cycle Time(Address transition min. width) real tm_A_tran_tWC_0, tm_A_tran_LastBit; reg flag_tWCtRC,flag_tWCtRC1; initial begin tm_A_tran_tWC_0 <= 0; flag_tWCtRC <= 1'b0; flag_tWCtRC1 <= 1'b0; end always @(posedge CEn or negedge CE2) flag_tWCtRC <= 1'b1; always @(negedge CEn or posedge CE2) flag_tWCtRC1 <= 1'b1; always @(A) begin if (CEn | ~CE2) tm_A_tran_tWC_0 <= $realtime; if (~CEn & CE2) flag_tWCtRC1 <= 1'b0; if ((CEn | ~CE2) & flag_tWCtRC & flag_tWCtRC1) begin flag_tWCtRC <= 1'b0; flag_tWCtRC1 <= 1'b0; if (((tWC-0.001) > $realtime-tm_A_tran_tWC_0) && ($realtime-tm_A_tran_tWC_0 > BusSkew)) begin $display("Error: tWC/tRC A Cycle min. width violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_tWC_0,tRC); end end tm_A_tran_LastBit <= $realtime; end //--------------- tRC/tWC : min. tRC=55 Read Cycle Time; (Address transition min. width) real tm_A_tran_tRC; initial begin tm_A_tran_tRC <= 0; end always @(A) begin tm_A_tran_tRC <= $realtime; begin if (((tRC-0.001) > $realtime-tm_A_tran_tRC) && ($realtime-tm_A_tran_tRC > BusSkew)) begin $display("Error: tWC/tRC A Cycle min. width violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_tRC,tRC); end end end //------------- tAW : min. 50 Address Valid to End of Write wire wWriteCycle_delay; //-- 20170529 always @(posedge WEn) begin if (tAW > $realtime-tm_A_tran_LastBit) $display("Error: tAW, Address transition to WEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_LastBit,tAW); end always @(posedge CEn) begin if ((wWriteCycle_delay) && (tAW > $realtime-tm_A_tran_LastBit)) $display("Error: tAW, Address transition to CEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_LastBit,tAW); end always @(posedge UBn) begin if ((wWriteCycle_delay) && (tAW > $realtime-tm_A_tran_LastBit)) $display("Error: tAW, Address transition to UBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_LastBit,tAW); end always @(posedge LBn) begin if ((wWriteCycle_delay) && (tAW > $realtime-tm_A_tran_LastBit)) $display("Error: tAW, Address transition to LBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_LastBit,tAW); end always @(negedge CE2) begin if ((wWriteCycle_delay) && (tAW > $realtime-tm_A_tran_LastBit)) $display("Error: tAW, Address transition to CE2 falling violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_A_tran_LastBit,tAW); end //------------- tCW : min. 50 Chip Enable to End of Write always @(posedge WEn) begin if (tCW > $realtime-tm_CEn_falling) $display("Error: tCW, CEn falling to WEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CEn_falling,tCW); if (tCW > $realtime-tm_CE2_rising) $display("Error: tCW, CE2 rising to WEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CE2_rising,tCW); end real temp_UBn, temp_2; always @(posedge UBn) begin temp_2 <= temp_UBn; if (tCW > $realtime-tm_CEn_falling) $display("Error: tCW, CEn falling to UBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CEn_falling,tCW); if (tCW > $realtime-tm_CE2_rising) $display("Error: tCW, CE2 rising to UBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CE2_rising,tCW); end always @(posedge LBn) begin if (tCW > $realtime-tm_CEn_falling) $display("Error: tCW, CEn falling to LBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CEn_falling,tCW); if (tCW > $realtime-tm_CE2_rising) $display("Error: tCW, CE2 rising to LBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CE2_rising,tCW); end always @(posedge CEn) begin if (tCW > $realtime-tm_CEn_falling) $display("Error: tCW, CEn falling to CEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CEn_falling,tCW); if (tCW > $realtime-tm_CE2_rising) $display("Error: tCW, CE2 rising to CEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_CE2_rising,tCW); end //------------- tBW : min 50 LBn,UBn Valid to End of Write real tm_UBn_falling,tm_LBn_falling; always @(negedge UBn) tm_UBn_falling <= $realtime; always @(negedge LBn) tm_LBn_falling <= $realtime; always @(posedge WEn) begin if (tBW > $realtime-tm_UBn_falling) $display("Error: tBW, UBn falling to WEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_UBn_falling,tCW); if (tBW > $realtime-tm_LBn_falling) $display("Error: tBW, LBn falling to WEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_LBn_falling,tCW); end always @(posedge CEn) begin if (tBW > $realtime-tm_UBn_falling) $display("Error: tBW, UBn falling to CEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_UBn_falling,tCW); if (tBW > $realtime-tm_LBn_falling) $display("Error: tBW, LBn falling to CEn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_LBn_falling,tCW); end always @(negedge CE2) begin if (tBW > $realtime-tm_UBn_falling) $display("Error: tBW, UBn falling to CE2 falling violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_UBn_falling,tCW); if (tBW > $realtime-tm_LBn_falling) $display("Error: tBW, LBn falling to CE2 falling violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_LBn_falling,tCW); end always @(posedge LBn) begin if (tBW > $realtime-tm_UBn_falling) $display("Error: tBW, UBn falling to LBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_UBn_falling,tCW); if (tBW > $realtime-tm_LBn_falling) $display("Error: tBW, LBn falling to LBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_LBn_falling,tCW); end always @(posedge UBn) begin if (tBW > $realtime-tm_UBn_falling) $display("Error: tBW, UBn falling to UBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_UBn_falling,tCW); if (tBW > $realtime-tm_LBn_falling) $display("Error: tBW, LBn falling to UBn rising violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_LBn_falling,tCW); end //---------------- tWP min. 45 Write Pulse Width real tm_WEn_falling; always @(negedge WEn) tm_WEn_falling <= $realtime; always @(posedge WEn) begin if ((tWP-0.001) > $realtime-tm_WEn_falling) $display("Error: tWP min. WEn width violation at time %t ps: Measure=%f ns Spec=%f ns", $realtime*10,$realtime-tm_WEn_falling,tWP); end //------------- tWHZ : max. 20 Write to Ouput in High-Z reg rWEn_tWHZ,rUBn_tWHZ,rLBn_tWHZ,rCEn_tWHZ,rCE2_tWHZ; reg rReadWriteCycle_tWHZ; reg rReadCycle,rWriteCycle; initial begin rWEn_tWHZ <= 1'b0; rUBn_tWHZ <= 1'b0; rLBn_tWHZ <= 1'b0; rCEn_tWHZ <= 1'b0; rCE2_tWHZ <= 1'b0; rReadWriteCycle_tWHZ <= 1'b0; rReadCycle <= 1'b0; rWriteCycle <= 1'b0; end always @(WEn) rWEn_tWHZ <= #tWHZ WEn; always @(negedge WEn) if (OEn==1'b0) rReadWriteCycle_tWHZ <= 1'b1; else rReadWriteCycle_tWHZ <= 1'b0; assign #(tWHZ+0.1) wReadCycle_delay = rReadCycle; //-- 20170525 assign #0.1 wReadCycle_1 = rReadCycle; assign #0.1 wWriteCycle_delay = rWriteCycle; always @(CEn or WEn or OEn) begin if (~CEn & WEn & ~OEn) rReadCycle <= 1'b1; else rReadCycle <= 1'b0; if (~CEn & ~WEn) rWriteCycle <= 1'b1; else rWriteCycle <= 1'b0; end always @(negedge rWEn_tWHZ) if ((wReadCycle_delay == 1'b1) && (DQ[14:0] !== 15'hz)) $display("Error: tWHZ min. WEn falling to DQ High-Z min. time violation at time %t ps", $realtime*10); //-- 20170525 endmodule