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(instance_block, configuration.getInstanceParameters(), factory_block),
220 int dev_numInputs = 0;
227 if (dev_letter ==
'U') {
238 UserWarning(*
this)<<
"VLO model parameter ignored for U digital device";
242 UserWarning(*
this)<<
"VHI model parameter ignored for U digital device";
246 UserWarning(*
this)<<
"VREF model parameter ignored for U digital device";
249 else if (dev_letter ==
'Y')
253 UserWarning(*
this)<<
"Y digital device (" <<
getName() <<
") is deprecated. Consider using U device instead.";
280 if (dev_type ==
"NOT" || dev_type ==
"INV")
282 if (dev_type ==
"NOT")
284 UserWarning(*
this)<<
"NOT gate type (" <<
getName() <<
") is deprecated. Consider using INV instead.";
290 else if (dev_type ==
"AND")
292 numInput = (dev_letter ==
'Y') ? 2 : dev_numInputs;
296 else if (dev_type ==
"NAND")
298 numInput = (dev_letter ==
'Y') ? 2 : dev_numInputs;
302 else if (dev_type ==
"OR")
304 numInput = (dev_letter ==
'Y') ? 2 : dev_numInputs;
308 else if (dev_type ==
"NOR")
310 numInput = (dev_letter ==
'Y') ? 2 : dev_numInputs;
314 else if (dev_type ==
"ADD")
320 else if (dev_type ==
"XOR")
326 else if (dev_type ==
"NXOR")
332 else if (dev_type ==
"DFF")
338 else if (dev_type ==
"DLTCH")
344 else if (dev_type ==
"BUF")
352 UserError0(*
this) <<
"Unknown digital device type " << dev_type;
362 Xyce::dout() <<
"Digital Device " <<
getName() <<
" has iBase = " <<
363 iBase <<
", oBase = " << oBase <<
", numExtVars = " <<
374 UserError0(*
this) <<
"this device must have more than one input.";
376 if ( (dev_numInputs != 0) && (instance_block.
numExtVars - iBase - numOutput != dev_numInputs) )
378 std::cout << instance_block.
numExtVars <<
" " << dev_numInputs <<
" " <<
numExtVars << std::endl;
379 UserError0(*
this) <<
"too few I/O nodes on instance line.";
386 UserError0(*
this) <<
"Incorrect number of nodes in digital device "
406 qlo.resize(numOutput);
407 ilo.resize(numOutput);
409 qhi.resize(numOutput);
410 ihi.resize(numOutput);
412 qref.resize(numInput);
413 iref.resize(numInput);
415 rilo.resize(numOutput);
416 rihi.resize(numOutput);
417 riref.resize(numInput);
420 glo.resize(numOutput);
421 ghi.resize(numOutput);
423 qInp.resize(numInput);
424 iInp.resize(numInput);
428 inpL.resize(numInput);
429 iTime.resize(numInput);
430 outL.resize(numOutput);
431 oTime.resize(numOutput);
451 if (dev_letter ==
'U')
496 else if (dev_letter ==
'Y')
566 jacStamp[iBase+i].push_back(iBase+i);
586 jacStamp[oBase+i].push_back(oBase+i);
626 const std::vector<int> & extLIDVecRef)
633 int numInt = intLIDVecRef.size();
634 int numExt = extLIDVecRef.size();
638 msg =
"Instance::registerLIDs:";
639 msg +=
"numInt != numIntVars";
640 N_ERH_ErrorMgr::report( N_ERH_ErrorMgr::DEV_FATAL,msg);
645 msg =
"Instance::registerLIDs:";
646 msg +=
"numExt != numExtVars";
647 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
662 if (dev_letter ==
'U')
671 else if (dev_letter ==
'Y')
708 int numSta = staLIDVecRef.size();
712 msg =
"Instance::registerStateLIDs:";
713 msg +=
"numSta != numStateVars";
714 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
781 int lo_present, hi_present;
783 (
row_Lo < 0) ? (lo_present = 0) : (lo_present = 1);
784 (
row_Hi < 0) ? (hi_present = 0) : (hi_present = 1);
790 if (dev_letter ==
'U')
794 UserError0(*
this) <<
"Internal error in Instance::registerJacLIDs() for " <<
getName();
801 li_jac_Ref[i][2] = jacLIDVec[li_jac_Ref[i][0]][li_jac_Ref[i][2]];
802 li_jac_Ref[i][4] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][4]];
803 li_jac_Ref[i][5] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][5]];
809 li_jac_Lo[i][2] = jacLIDVec[li_jac_Lo[i][0]][li_jac_Lo[i][2]];
810 li_jac_Lo[i][4] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][4]];
811 li_jac_Lo[i][5] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][5]];
817 li_jac_Hi[i][2] = jacLIDVec[li_jac_Hi[i][0]][li_jac_Hi[i][2]];
818 li_jac_Hi[i][4] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][4]];
819 li_jac_Hi[i][5] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][5]];
823 else if (dev_letter ==
'Y')
839 li_jac_Ref[i][2] = jacLIDVec[li_jac_Ref[i][0]][li_jac_Ref[i][2]];
840 li_jac_Ref[i][4] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][4]];
841 li_jac_Ref[i][5] = jacLIDVec[li_jac_Ref[i][3]][li_jac_Ref[i][5]];
859 li_jac_Lo[i][2] = jacLIDVec[li_jac_Lo[i][0]][li_jac_Lo[i][2]];
860 li_jac_Lo[i][4] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][4]];
861 li_jac_Lo[i][5] = jacLIDVec[li_jac_Lo[i][3]][li_jac_Lo[i][5]];
879 li_jac_Hi[i][2] = jacLIDVec[li_jac_Hi[i][0]][li_jac_Hi[i][2]];
880 li_jac_Hi[i][4] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][4]];
881 li_jac_Hi[i][5] = jacLIDVec[li_jac_Hi[i][3]][li_jac_Hi[i][5]];
907 bool bsuccess =
true;
908 double v_poslo, v_poshi, v_posref, v_neg;
909 double elapsed, time, frac, lastT;
911 double transitionTime;
912 bool changeState =
false;
913 bool clocking =
false;
915 bool toPrint =
false;
944 v_neg = solVector[
li_Inp[i]];
947 elapsed = time - transitionTime;
961 oldStaVector[li_transitionTimeInp[i]] = transitionTime;
964 iTime[i] = transitionTime;
966 staVector[li_transitionTimeInp[i]] = transitionTime;
968 if (currentState == 0)
1008 inpL[i] = (currentState == 1);
1009 (li_Ref >= 0) ? (vOld = oldSolVector[li_Ref]) : (vOld =
model_.
vref);
1010 vOld = oldSolVector[li_Inp[i]] - vOld;
1011 if (fabs(
vcapref[i]+vOld) < 1.e-12)
1024 staVector[li_transitionTimeInp[i]] = time - del;
1031 if (
iTime[i] > lastT)
1073 outL[1] = (inpL[0] & inpL[1]) | (inpL[1] & inpL[2]) | (inpL[0] & inpL[2]);
1096 if ((
inpL[0] == 1) && (
inpL[1] == 0))
1103 else if ((
inpL[0] == 0) && (
inpL[1] == 1))
1110 else if ((
inpL[0] == 0) && (
inpL[1] == 0))
1118 else if (
inpL[2] == 1)
1148 if (clocking &&
inpL[2] ==1)
1156 else if (clocking &&
inpL[2] ==0)
1161 outL[1] = oldStaVector[li_currentStateOut[1]];
1171 else if (
inpL[0] == 0 &&
inpL[1] == 1)
1176 else if (
inpL[0] == 0 &&
inpL[1] == 0)
1205 std::string msg(
"Insufficient initial conditions supported in digital device");
1206 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1217 if (currentState == 1)
1222 if (curr !=
outL[i])
1224 if (
oTime[i] <= time)
1226 currentState = 1-currentState;
1227 transitionTime =
oTime[i];
1239 staVector[li_transitionTimeOut[i]] = transitionTime;
1242 v_neg = solVector[
li_Out[i]];
1244 elapsed = time - transitionTime;
1246 if (currentState == 0)
1248 else if (currentState == 1)
1252 std::string msg(
"Instance::updateSecondaryState: unrecognized state");
1253 N_ERH_ErrorMgr::report(N_ERH_ErrorMgr::DEV_FATAL, msg);
1256 frac = exp(-elapsed);
1257 if (transitionTime == 0)
1272 if (currentState == 0)
1283 rilo[i] =
glo[i]*(v_poslo-v_neg);
1284 rihi[i] =
ghi[i]*(v_poshi-v_neg);
1286 vcaplo[i] = v_poslo-v_neg;
1287 vcaphi[i] = v_poshi-v_neg;
1311 bool bsuccess =
true;
1352 ( std::vector<N_UTL_BreakPoint> & breakPointTimes )
1354 if (breakTime > getSolverState().currTime)
1356 breakPointTimes.push_back(breakTime);
1386 Xyce::dout() <<
"Device " <<
getName() <<
" changed state & accepted time step at "
1388 <<
"change at Device " <<
getName() <<
" at time "
1390 << delta << std::endl << std::endl;
1414 bool bsuccess =
true;
1418 Xyce::dout() << subsection_divider << std::endl;
1419 Xyce::dout() <<
" Instance::loadDAEQVector" << std::endl;
1420 Xyce::dout() <<
" name = " <<
getName() <<std::endl;
1427 Xyce::dout() <<
" qlo[" << i <<
"] = " <<
qlo[i] << std::endl;
1428 Xyce::dout() <<
" qhi[" << i <<
"] = " <<
qhi[i] << std::endl;
1452 Xyce::dout() <<
" qref[" << i <<
"] = " <<
qref[i] << std::endl;
1482 bool bsuccess =
true;
1490 Xyce::dout() << subsection_divider << std::endl;
1491 Xyce::dout() <<
" Instance::loadDAEFVector" << std::endl;
1492 Xyce::dout() <<
" name = " <<
getName() <<std::endl;
1499 Xyce::dout() <<
" rilo[" << i <<
"] = " <<
rilo[i] << std::endl;
1500 Xyce::dout() <<
" rihi[" << i <<
"] = " <<
rihi[i] << std::endl;
1524 Xyce::dout() <<
" riref[" << i <<
"] = " <<
riref[i] << std::endl;
1539 Xyce::dout() << subsection_divider << std::endl;
1562 bool bsuccess =
true;
1568 Xyce::dout() << subsection_divider <<std::endl;
1569 Xyce::dout() <<
" Instance::loadDAEdQdx" << std::endl;
1570 Xyce::dout() <<
" name = " <<
getName() << std::endl;
1575 Xyce::dout() <<
"\nLoading DIGITAL dQdx matrix\n";
1576 Xyce::dout() <<
"Capacitance lo: " <<
model_.
clo << std::endl;
1577 Xyce::dout() <<
"Capacitance hi: " <<
model_.
chi << std::endl;
1578 Xyce::dout() <<
"Capacitance load: " <<
model_.
cload << std::endl;
1579 Xyce::dout() <<
"DONE DIGITAL dQdx matrix LOAD\n";
1656 bool bsuccess =
true;
1661 Xyce::dout() << subsection_divider <<std::endl;
1662 Xyce::dout() <<
" Instance::loadDAEdFdx" << std::endl;
1689 Xyce::dout() <<
" glo[" << i <<
"] = " <<
glo[i] << std::endl;
1690 Xyce::dout() <<
" ghi[" << i <<
"] = " <<
ghi[i] << std::endl;
1698 (*dFdxMatPtr)[
li_Lo][li_jac_Lo[i][2]] -=
glo[i];
1700 (*dFdxMatPtr)[
li_Out[i]][li_jac_Lo[i][4]] -=
glo[i];
1702 (*dFdxMatPtr)[
li_Out[i]][li_jac_Lo[i][5]] +=
glo[i];
1714 (*dFdxMatPtr)[
li_Hi][li_jac_Hi[i][2]] -=
ghi[i];
1716 (*dFdxMatPtr)[
li_Out[i]][li_jac_Hi[i][4]] -=
ghi[i];
1718 (*dFdxMatPtr)[
li_Out[i]][li_jac_Hi[i][5]] +=
ghi[i];
1759 std::vector<Instance*>::iterator iter;
1763 for (iter=first; iter!=last; ++iter)
1765 (*iter)->processParams();
1784 :
DeviceModel(MB, configuration.getModelParameters(), factory_block)
1802 UserError0(*
this) <<
"Zero load resistance in inputs";
1820 std::vector<Instance*>::iterator iter;
1824 for (iter=first; iter!=last; ++iter)
1842 std::vector<Instance*>::const_iterator iter;
1850 os <<
"Number of digital instances: " << isize << std::endl;
1851 os <<
" name\t\tmodelName\tParameters" << std::endl;
1853 for (i = 0, iter = first; iter != last; ++iter, ++i)
1855 os <<
" " << i <<
": " << (*iter)->getName() <<
"\t";
1881 for (std::vector<Instance *>::const_iterator it = instanceContainer.begin(); it != instanceContainer.end(); ++it)
1896 .registerDevice(
"inv", 1)
1897 .registerDevice(
"not",1)
1898 .registerDevice(
"and", 1)
1899 .registerDevice(
"nand", 1)
1900 .registerDevice(
"or", 1)
1901 .registerDevice(
"nor", 1)
1902 .registerDevice(
"add", 1)
1903 .registerDevice(
"xor", 1)
1904 .registerDevice(
"nxor", 1)
1905 .registerDevice(
"dff", 1)
1906 .registerDevice(
"buf", 1)
1907 .registerDevice(
"dltch", 1)
1908 .registerModelType(
"dig", 1);