45 #include <Xyce_config.h>
48 #include <N_UTL_Misc.h>
68 #include <N_ERH_ErrorMgr.h>
69 #include <N_UTL_BreakPoint.h>
71 #include <N_LAS_Vector.h>
72 #include <N_LAS_Matrix.h>
90 .setDescription(
"Vector of initial values for output(s)");
101 .setDescription(
"Internal low state supply voltage");
105 .setDescription(
"Internal high state supply voltage");
109 .setDescription(
"Internal reference voltage for inputs");
113 .setDescription(
"Capacitance between output node and low reference");
117 .setDescription(
"Capacitance between output node and high reference");
121 .setDescription(
"Capacitance between input node and input reference");
125 .setDescription(
"Resistance between input node and input reference");
129 .setDescription(
"Low state resistance between output node and low reference");
133 .setDescription(
"Low state resitance between output node and high reference");
137 .setDescription(
"Switching time transition to low state");
141 .setDescription(
"Minimum voltage to switch to low state");
145 .setDescription(
"Maximum voltage to switch to low state");
149 .setDescription(
"High state resistance between output node and low reference");
153 .setDescription(
"High state resistance between output node and high reference");
157 .setDescription(
"Switching time transition to high state");
161 .setDescription(
"Minimum voltage to switch to high state");
165 .setDescription(
"Maximum voltage to switch to high state");
169 .setDescription(
"Delay time of device");
203 :
DeviceInstance(IB, configuration.getInstanceParameters(), factory_block),
213 int i, tokenCount = 0, dev_numInputs = 0;
215 if (tokenCount == 2 || tokenCount == 3)
218 p1 =
getName().find_first_of(
'%');
219 p2 = p1 + 1 +
getName().substr(p1+1).find_first_of(
'%');
223 p3 =
getName().find_last_of(
'%');
225 dev_numInputs = std::atoi(
getName().substr(p3+1).c_str());
232 std::string dev_letter =
getName().substr(p1-1,1);
233 if (dev_letter ==
"U"){
242 UserWarning(*
this)<<
"VLO model parameter ignored for U digital device";
246 UserWarning(*
this)<<
"VHI model parameter ignored for U digital device";
250 UserWarning(*
this)<<
"VREF model parameter ignored for U digital device";
253 else if (dev_letter ==
"Y")
257 UserWarning(*
this)<<
"Y digital device (" <<
getName() <<
") is deprecated. Consider using U device instead.";
281 std::string dev_type(
getName().substr(p1+1,p2-p1-1));
282 if (dev_type ==
"NOT" || dev_type ==
"INV")
284 if (dev_type ==
"NOT")
286 UserWarning(*
this)<<
"NOT gate type (" <<
getName() <<
") is deprecated. Consider using INV instead.";
292 else if (dev_type ==
"AND")
298 else if (dev_type ==
"NAND")
304 else if (dev_type ==
"OR")
310 else if (dev_type ==
"NOR")
316 else if (dev_type ==
"ADD")
322 else if (dev_type ==
"XOR")
328 else if (dev_type ==
"NXOR")
334 else if (dev_type ==
"DFF")
347 else if (dev_type ==
"BUF")
355 UserError0(*
this) <<
"Unknown digital device type " << dev_type;
360 std::string msg(
"Internal error in digital device name: ");
362 std::ostringstream oss;
364 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, oss.str());
373 Xyce::dout() <<
"Digital Device " <<
getName() <<
" has iBase = " <<
374 iBase <<
", oBase = " << oBase <<
", numExtVars = " <<
385 UserError0(*
this) <<
"this device must have more than one input.";
387 if ( (dev_numInputs != 0) && (IB.
numExtVars - iBase - numOutput != dev_numInputs) )
390 UserError0(*
this) <<
"too few I/O nodes on instance line.";
397 UserError0(*
this) <<
"Incorrect number of nodes in digital device "
417 qlo.resize(numOutput);
418 ilo.resize(numOutput);
420 qhi.resize(numOutput);
421 ihi.resize(numOutput);
423 qref.resize(numInput);
424 iref.resize(numInput);
426 rilo.resize(numOutput);
427 rihi.resize(numOutput);
428 riref.resize(numInput);
431 glo.resize(numOutput);
432 ghi.resize(numOutput);
434 qInp.resize(numInput);
435 iInp.resize(numInput);
439 inpL.resize(numInput);
440 iTime.resize(numInput);
441 outL.resize(numOutput);
442 oTime.resize(numOutput);
463 if (dev_letter ==
"U")
508 else if (dev_letter ==
"Y")
577 jacStamp[iBase+i].push_back(iBase+i);
597 jacStamp[oBase+i].push_back(oBase+i);
638 const std::vector<int> & extLIDVecRef)
645 int numInt = intLIDVecRef.size();
646 int numExt = extLIDVecRef.size();
650 msg =
"Instance::registerLIDs:";
651 msg +=
"numInt != numIntVars";
652 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
657 msg =
"Instance::registerLIDs:";
658 msg +=
"numExt != numExtVars";
659 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
674 if (dev_letter ==
"U")
683 else if (dev_letter ==
"Y")
720 int numSta = staLIDVecRef.size();
724 msg =
"Instance::registerStateLIDs:";
725 msg +=
"numSta != numStateVars";
726 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
794 int lo_present, hi_present;
796 (
row_Lo < 0) ? (lo_present = 0) : (lo_present = 1);
797 (
row_Hi < 0) ? (hi_present = 0) : (hi_present = 1);
803 if (dev_letter ==
"U")
807 UserError0(*
this) <<
"Internal error in Instance::registerJacLIDs() for " <<
getName();
814 li_jac_Ref[i][2] = jacLIDVec[li_jac_Ref[i][0]][li_jac_Ref[i][2]];
815 li_jac_Ref[i][4] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][4]];
816 li_jac_Ref[i][5] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][5]];
822 li_jac_Lo[i][2] = jacLIDVec[li_jac_Lo[i][0]][li_jac_Lo[i][2]];
823 li_jac_Lo[i][4] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][4]];
824 li_jac_Lo[i][5] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][5]];
830 li_jac_Hi[i][2] = jacLIDVec[li_jac_Hi[i][0]][li_jac_Hi[i][2]];
831 li_jac_Hi[i][4] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][4]];
832 li_jac_Hi[i][5] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][5]];
836 else if (dev_letter ==
"Y")
852 li_jac_Ref[i][2] = jacLIDVec[li_jac_Ref[i][0]][li_jac_Ref[i][2]];
853 li_jac_Ref[i][4] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][4]];
854 li_jac_Ref[i][5] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][5]];
872 li_jac_Lo[i][2] = jacLIDVec[li_jac_Lo[i][0]][li_jac_Lo[i][2]];
873 li_jac_Lo[i][4] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][4]];
874 li_jac_Lo[i][5] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][5]];
892 li_jac_Hi[i][2] = jacLIDVec[li_jac_Hi[i][0]][li_jac_Hi[i][2]];
893 li_jac_Hi[i][4] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][4]];
894 li_jac_Hi[i][5] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][5]];
914 bool bsuccess =
true;
915 double v_poslo, v_poshi, v_posref, v_neg;
916 double elapsed, time, frac, lastT;
918 double transitionTime;
919 bool changeState =
false;
920 bool clocking =
false;
922 bool toPrint =
false;
953 v_neg = solVector[
li_Inp[i]];
956 elapsed = time - transitionTime;
970 oldStaVector[li_transitionTimeInp[i]] = transitionTime;
973 iTime[i] = transitionTime;
975 staVector[li_transitionTimeInp[i]] = transitionTime;
977 if (currentState == 0)
1017 inpL[i] = (currentState == 1);
1018 (li_Ref >= 0) ? (vOld = oldSolVector[li_Ref]) : (vOld =
model_.
vref);
1019 vOld = oldSolVector[li_Inp[i]] - vOld;
1020 if (fabs(
vcapref[i]+vOld) < 1.e-12)
1033 staVector[li_transitionTimeInp[i]] = time - del;
1040 if (
iTime[i] > lastT)
1073 outL[1] = (inpL[0] & inpL[1]) | (inpL[1] & inpL[2]) | (inpL[0] & inpL[2]);
1098 if ((
inpL[0] == 1) && (
inpL[1] == 0))
1105 else if ((
inpL[0] == 0) && (
inpL[1] == 1))
1112 else if ((
inpL[0] == 0) && (
inpL[1] == 0))
1119 else if (
inpL[2] == 1)
1142 if (clocking &&
inpL[2] ==1)
1150 else if (clocking &&
inpL[2] ==0)
1155 outL[1] = oldStaVector[li_currentStateOut[1]];
1165 else if (
inpL[0] == 0 &&
inpL[1] == 1)
1170 else if (
inpL[0] == 0 &&
inpL[1] == 0)
1199 std::string msg(
"Insufficient initial conditions supported in digital device");
1200 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1211 if (currentState == 1)
1216 if (curr !=
outL[i])
1218 if (
oTime[i] <= time)
1220 currentState = 1-currentState;
1221 transitionTime =
oTime[i];
1233 staVector[li_transitionTimeOut[i]] = transitionTime;
1236 v_neg = solVector[
li_Out[i]];
1238 elapsed = time - transitionTime;
1240 if (currentState == 0)
1242 else if (currentState == 1)
1246 std::string msg(
"Instance::updateSecondaryState: unrecognized state");
1247 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1250 frac = exp(-elapsed);
1251 if (transitionTime == 0)
1266 if (currentState == 0)
1277 rilo[i] =
glo[i]*(v_poslo-v_neg);
1278 rihi[i] =
ghi[i]*(v_poshi-v_neg);
1280 vcaplo[i] = v_poslo-v_neg;
1281 vcaphi[i] = v_poshi-v_neg;
1304 bool bsuccess =
true;
1346 ( std::vector<N_UTL_BreakPoint> & breakPointTimes )
1348 if (breakTime > getSolverState().currTime)
1350 breakPointTimes.push_back(breakTime);
1372 bool bsuccess =
true;
1377 Xyce::dout() << subsection_divider << std::endl;
1378 Xyce::dout() <<
" Instance::loadDAEQVector" << std::endl;
1379 Xyce::dout() <<
" name = " <<
getName() <<std::endl;
1386 Xyce::dout() <<
" qlo[" << i <<
"] = " <<
qlo[i] << std::endl;
1387 Xyce::dout() <<
" qhi[" << i <<
"] = " <<
qhi[i] << std::endl;
1411 Xyce::dout() <<
" qref[" << i <<
"] = " <<
qref[i] << std::endl;
1441 bool bsuccess =
true;
1450 Xyce::dout() << subsection_divider << std::endl;
1451 Xyce::dout() <<
" Instance::loadDAEFVector" << std::endl;
1452 Xyce::dout() <<
" name = " <<
getName() <<std::endl;
1459 Xyce::dout() <<
" rilo[" << i <<
"] = " <<
rilo[i] << std::endl;
1460 Xyce::dout() <<
" rihi[" << i <<
"] = " <<
rihi[i] << std::endl;
1484 Xyce::dout() <<
" riref[" << i <<
"] = " <<
riref[i] << std::endl;
1499 Xyce::dout() << subsection_divider << std::endl;
1522 bool bsuccess =
true;
1529 Xyce::dout() << subsection_divider <<std::endl;
1530 Xyce::dout() <<
" Instance::loadDAEdQdx" << std::endl;
1531 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1536 Xyce::dout() <<
"\nLoading DIGITAL dQdx matrix\n";
1537 Xyce::dout() <<
"Capacitance lo: " <<
model_.
clo << std::endl;
1538 Xyce::dout() <<
"Capacitance hi: " <<
model_.
chi << std::endl;
1539 Xyce::dout() <<
"Capacitance load: " <<
model_.
cload << std::endl;
1540 Xyce::dout() <<
"DONE DIGITAL dQdx matrix LOAD\n";
1617 bool bsuccess =
true;
1623 Xyce::dout() << subsection_divider <<std::endl;
1624 Xyce::dout() <<
" Instance::loadDAEdFdx" << std::endl;
1651 Xyce::dout() <<
" glo[" << i <<
"] = " <<
glo[i] << std::endl;
1652 Xyce::dout() <<
" ghi[" << i <<
"] = " <<
ghi[i] << std::endl;
1660 (*dFdxMatPtr)[
li_Lo][li_jac_Lo[i][2]] -=
glo[i];
1662 (*dFdxMatPtr)[
li_Out[i]][li_jac_Lo[i][4]] -=
glo[i];
1664 (*dFdxMatPtr)[
li_Out[i]][li_jac_Lo[i][5]] +=
glo[i];
1676 (*dFdxMatPtr)[
li_Hi][li_jac_Hi[i][2]] -=
ghi[i];
1678 (*dFdxMatPtr)[
li_Out[i]][li_jac_Hi[i][4]] -=
ghi[i];
1680 (*dFdxMatPtr)[
li_Out[i]][li_jac_Hi[i][5]] +=
ghi[i];
1721 std::vector<Instance*>::iterator iter;
1725 for (iter=first; iter!=last; ++iter)
1727 (*iter)->processParams();
1746 :
DeviceModel(MB, configuration.getModelParameters(), factory_block)
1764 UserError0(*
this) <<
"Zero load resistance in inputs";
1782 std::vector<Instance*>::iterator iter;
1786 for (iter=first; iter!=last; ++iter)
1804 std::vector<Instance*>::const_iterator iter;
1812 os <<
"Number of digital instances: " << isize << std::endl;
1813 os <<
" name\t\tmodelName\tParameters" << std::endl;
1815 for (i = 0, iter = first; iter != last; ++iter, ++i)
1817 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1843 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1868 int p1 =
getName().find_first_of(
'%');
1869 std::string dev_letter = (p1 != std::string::npos) ?
getName().substr(p1-1,1) :
"";
1879 .registerDevice(
"inv", 1)
1880 .registerDevice(
"not",1)
1881 .registerDevice(
"and", 1)
1882 .registerDevice(
"nand", 1)
1883 .registerDevice(
"or", 1)
1884 .registerDevice(
"nor", 1)
1885 .registerDevice(
"add", 1)
1886 .registerDevice(
"xor", 1)
1887 .registerDevice(
"nxor", 1)
1888 .registerDevice(
"dff", 1)
1889 .registerDevice(
"buf", 1)
1890 .registerModelType(
"dig", 1);