summaryrefslogtreecommitdiff
path: root/OSCAD/LPCSim/LUT/ids.cpp
diff options
context:
space:
mode:
authorJayaram Pai2014-05-19 11:02:57 +0530
committerJayaram Pai2014-05-19 11:02:57 +0530
commit8377256e7d90aa7ba1cb51f6164e99f81e2eb53c (patch)
tree5afcc8e82d7f7d4f6fbff900520bd8f05eb343ca /OSCAD/LPCSim/LUT/ids.cpp
downloadFreeEDA-8377256e7d90aa7ba1cb51f6164e99f81e2eb53c.tar.gz
FreeEDA-8377256e7d90aa7ba1cb51f6164e99f81e2eb53c.tar.bz2
FreeEDA-8377256e7d90aa7ba1cb51f6164e99f81e2eb53c.zip
initial commit
Diffstat (limited to 'OSCAD/LPCSim/LUT/ids.cpp')
-rw-r--r--OSCAD/LPCSim/LUT/ids.cpp394
1 files changed, 394 insertions, 0 deletions
diff --git a/OSCAD/LPCSim/LUT/ids.cpp b/OSCAD/LPCSim/LUT/ids.cpp
new file mode 100644
index 0000000..cc6f489
--- /dev/null
+++ b/OSCAD/LPCSim/LUT/ids.cpp
@@ -0,0 +1,394 @@
+/****************************************************************************
+ This routine assumes the existance of file named "vbs_files.txt"
+ and the files decribed in the that file in current directory.
+ File vbs_files.txt contains vbs values and corresponding Id-Vds_Vgs file names
+ e.g. one entry may be 0.2 vbs_0.2.txt
+*****************************************************************************/
+
+/******************* Header *********************************/
+#include <iostream>
+#include <iomanip>
+#include <fstream>
+#include <math.h>
+#include <cstdlib>
+#include <string.h>
+
+
+struct CoeffStruct{
+ double x;
+ double y;
+ double z;
+};
+
+class NaturalCubicSpline1D{
+public:
+ double ValueAtX(double x);
+ void initialize(int n,double* xData,double* yData);
+ NaturalCubicSpline1D(int NO_OF_POINTS,double* xData,double* yData); //Read from array
+ NaturalCubicSpline1D(); //User input
+ ~NaturalCubicSpline1D();
+
+private:
+ void DetermineCoeff();
+ int NO_OF_POINTS;
+ CoeffStruct* coeffsArray;
+};
+
+class yCSpair{
+public:
+ double y;
+ NaturalCubicSpline1D xCubicSpline;
+ yCSpair();
+ ~yCSpair();
+};
+
+class CubicCubic{
+public:
+ double evaluate(double x,double y);
+ void Initialize(char* Id_Vd_Vg);
+ const CubicCubic & operator=(const CubicCubic &rhs);
+ CubicCubic(char* Id_Vd_Vg);
+ CubicCubic(char* yfileName,char* xzfileName);
+ CubicCubic(int no_yPoints, double yArray[],int *pxArray,double** xArray,double** zArray);
+ CubicCubic();
+ ~CubicCubic();
+private:
+ int noYPoints;
+ yCSpair *CubicSplines1D;
+};
+
+class IdVbs{
+public:
+ double Evaluate(double vds,double vgs,double vbs);
+ void Initialize(double vbs);
+ IdVbs();
+ ~IdVbs();
+private:
+ double vbs_l,vbs_h; //vbs lies in interval [vbs_l,vbs_h]
+ CubicCubic cc_l;
+ CubicCubic cc_h;
+};
+/******************* Header *********************************/
+
+
+/********************* SciLab Callable Routine *******************************/
+//extern "C" _declspec(dllexport)
+extern "C"
+void ids_c( double *vds,
+ double *vgs,
+ double *vbs,
+ double *ids){
+ IdVbs id;
+ *ids=id.Evaluate(*vds,*vgs,*vbs);
+}
+
+
+/****************************************************/
+using namespace std;
+
+double NaturalCubicSpline1D::ValueAtX(double x){
+ /* x < Start Point first polynomial to be used
+ x > End Point last polynomial to be used
+ */
+
+ // Find the segment where x lies
+ int i=0; // i is used outside loop
+ for(i=0;i<NO_OF_POINTS-2;++i){ // upto NO_OF_POINTS-3
+ if( x<=coeffsArray[i+1].x) { // serially increment so valid
+ break;
+ }
+ }
+ //Evaluate the function
+ double value=0,Bi=0,hi=1;
+ hi = coeffsArray[i+1].x - coeffsArray[i].x;
+ Bi = -hi*(coeffsArray[i+1].z + 2*coeffsArray[i].z)/6 + (coeffsArray[i+1].y - coeffsArray[i].y)/hi;
+ double xti=(x - coeffsArray[i].x);
+ value = coeffsArray[i].y + xti*(Bi + xti*(coeffsArray[i].z/2 + xti*(coeffsArray[i+1].z - coeffsArray[i].z)/(6*hi)));
+ return value;
+}
+
+void NaturalCubicSpline1D::DetermineCoeff(){
+ double* u;
+ u=new double[NO_OF_POINTS];
+ double* v;
+ v=new double[NO_OF_POINTS];
+
+ u[0]=v[0]=0; // not to be used
+ double h1,h0,b1,b0;
+
+ h0=coeffsArray[1].x - coeffsArray[0].x;
+ h1=coeffsArray[2].x - coeffsArray[1].x;
+
+ b0=(1/h0)*(coeffsArray[1].y - coeffsArray[0].y);
+ b1=(1/h1)*(coeffsArray[2].y - coeffsArray[1].y);
+
+ u[1]=2*( h0 + h1 );
+ v[1]=6*( b1 - b0 );
+
+ for(int i=2;i<NO_OF_POINTS;++i){
+ h0=h1;
+ b0=b1;
+ h1=coeffsArray[i+1].x - coeffsArray[i].x;
+ b1=(1/h1)*(coeffsArray[i+1].y - coeffsArray[i].y);
+ u[i]=2*(h1+h0) - h0*h0/u[i-1];
+ v[i]=6*(b1-b0) - h0*v[i-1]/u[i-1];
+ }
+
+ coeffsArray[0].z = coeffsArray[NO_OF_POINTS-1].z=0; //Z(n-1) = Z(0) = 0
+ for(int i=NO_OF_POINTS-2;i>0;--i){
+ h1=coeffsArray[i+1].x - coeffsArray[i].x;
+ coeffsArray[i].z = (v[i] - h1*coeffsArray[i+1].z ) / u[i];
+ }
+}
+
+void NaturalCubicSpline1D::initialize(int n,double* xData,double* yData){
+ NO_OF_POINTS=n;
+ coeffsArray=new CoeffStruct[NO_OF_POINTS];
+ for(int i=0;i<NO_OF_POINTS;i++){
+ coeffsArray[i].x=xData[i];
+ coeffsArray[i].y=yData[i];
+ }
+ DetermineCoeff();
+}
+
+NaturalCubicSpline1D::NaturalCubicSpline1D(int n,double* xData,double* yData){
+ NO_OF_POINTS=n;
+ coeffsArray=new CoeffStruct[NO_OF_POINTS];
+ for(int i=0;i<NO_OF_POINTS;i++){
+ coeffsArray[i].x=xData[i];
+ coeffsArray[i].y=yData[i];
+ }
+ DetermineCoeff();
+}
+
+
+NaturalCubicSpline1D::NaturalCubicSpline1D(){
+}
+
+NaturalCubicSpline1D::~NaturalCubicSpline1D(){
+ delete [] coeffsArray;
+ coeffsArray=0;
+
+}
+
+
+
+double CubicCubic::evaluate(double x,double y){
+ double* yData=0;
+ double* zData=0;
+ yData=new double[noYPoints]; //actually y data for fixed x
+ zData=new double[noYPoints]; //actually z data for fixed x
+ for(int i=0;i<noYPoints;++i){
+ yData[i]=CubicSplines1D[i].y;
+ zData[i]=CubicSplines1D[i].xCubicSpline.ValueAtX(x);
+ }
+ NaturalCubicSpline1D yzCubicSpline(noYPoints,yData,zData); //y,z pair for fixed x=x
+ return yzCubicSpline.ValueAtX(y);
+}
+
+void CubicCubic::Initialize(char* Id_Vd_Vg){
+ ifstream idvdvg_file;
+ int n_diffVgs,n_diffVds;
+ idvdvg_file.open(Id_Vd_Vg);
+ if(!idvdvg_file.is_open()){cout<<"Failed to open file named: "<<Id_Vd_Vg<<endl; exit(1);}
+
+ idvdvg_file>>n_diffVgs;
+ idvdvg_file>>n_diffVds;
+
+ noYPoints=n_diffVgs;
+ CubicSplines1D= new yCSpair[noYPoints];
+
+ double* vds_array;
+ double* ids_array;
+ vds_array=new double[n_diffVds];
+ ids_array=new double[n_diffVds];
+
+ int index;
+ double vds;
+ double ids;
+ double vgs;
+
+ for(int i=0;i<n_diffVgs;++i){
+ for(int j=0;j<n_diffVds;++j){
+ if(idvdvg_file.eof()) {cout<<"End if file earlier than expected File Named: "<<Id_Vd_Vg<<endl; exit(1);}
+ idvdvg_file>>index;
+ idvdvg_file>>vds;
+ idvdvg_file>>ids;
+ idvdvg_file>>vgs;
+ CubicSplines1D[i].y=vgs; //repeat avoid
+ vds_array[j]=vds;
+ ids_array[j]=ids;
+ }
+ CubicSplines1D[i].xCubicSpline.initialize(n_diffVds,vds_array,ids_array);
+ }
+}
+const CubicCubic & CubicCubic::operator=(const CubicCubic &rhs){
+ if (this != &rhs) { // make sure not same object
+
+ for(int i=0;i<noYPoints;++i){ //free the old memory
+ CubicSplines1D[i].~yCSpair();
+ }
+
+ noYPoints=rhs.noYPoints; // assign new values
+ CubicSplines1D=rhs.CubicSplines1D; // pointer assigned
+ }
+ return *this; // Return ref for multiple assignment
+}
+
+CubicCubic::CubicCubic(char* Id_Vd_Vg){
+ ifstream idvdvg_file;
+ int n_diffVgs,n_diffVds;
+ idvdvg_file.open(Id_Vd_Vg);
+ if(!idvdvg_file.is_open()){cout<<"Failed to open file named: "<<Id_Vd_Vg<<endl; exit(1);}
+
+ idvdvg_file>>n_diffVgs;
+ idvdvg_file>>n_diffVds;
+
+ noYPoints=n_diffVgs;
+ CubicSplines1D= new yCSpair[noYPoints];
+
+ double* vds_array;
+ double* ids_array;
+ vds_array=new double[n_diffVds];
+ ids_array=new double[n_diffVds];
+
+ int index;
+ double vds;
+ double ids;
+ double vgs;
+
+ for(int i=0;i<n_diffVgs;++i){
+ for(int j=0;j<n_diffVds;++j){
+ if(idvdvg_file.eof()) {cout<<"End if file earlier than expected File Named: "<<Id_Vd_Vg<<endl; exit(1);}
+ idvdvg_file>>index;
+ idvdvg_file>>vds;
+ idvdvg_file>>ids;
+ idvdvg_file>>vgs;
+ CubicSplines1D[i].y=vgs;
+ vds_array[j]=vds;
+ ids_array[j]=ids;
+ }
+ CubicSplines1D[i].xCubicSpline.initialize(n_diffVds,vds_array,ids_array);
+ }
+}
+
+
+CubicCubic::CubicCubic(int no_yPoints, double yArray[],int *pxArray,double* xArray[],double* zArray[]){
+ noYPoints=no_yPoints;
+ CubicSplines1D= new yCSpair[noYPoints];
+ for(int i=0;i<noYPoints;++i){
+ CubicSplines1D[i].y=yArray[i];
+ CubicSplines1D[i].xCubicSpline.initialize(pxArray[i],xArray[i],zArray[i]);
+ }
+}
+
+CubicCubic::CubicCubic(char* yfileName,char* xzfileName){
+ ifstream yf,xzf;
+ yf.open(yfileName);
+ xzf.open(xzfileName);
+ int n=1;
+ xzf>>n;
+ double* vds_array;
+ double* ids_array;
+ vds_array=new double[n];
+ ids_array=new double[n];
+
+ if(!yf.is_open() || !xzf.is_open()){cout<<"Failed to open file "<<yfileName<<endl; exit(3);}
+ else{
+ yf>>noYPoints;
+ CubicSplines1D= new yCSpair[noYPoints];
+ for(int i=0;i<noYPoints;++i){
+ yf>>CubicSplines1D[i].y;
+ for(int j=0;j<n;++j){
+ xzf>>vds_array[j];
+ xzf>>ids_array[j];
+ }
+
+ CubicSplines1D[i].xCubicSpline.initialize(n,vds_array,ids_array);
+ }
+ }
+}
+
+CubicCubic::CubicCubic(){
+}
+
+CubicCubic::~CubicCubic(){
+ delete [] CubicSplines1D;
+ CubicSplines1D=0;
+}
+
+yCSpair::yCSpair(){
+}
+
+yCSpair::~yCSpair(){
+}
+
+double IdVbs::Evaluate(double vds,double vgs,double vbs){
+ if(vbs_l<=vbs && vbs<vbs_h) {
+ }
+ else{
+ Initialize(vbs);
+ }
+ double y1,y2,value;
+ y1=cc_l.evaluate(vds,vgs);
+ y2=cc_h.evaluate(vds,vgs);
+ value=y1+(vbs-vbs_l)*(y2-y1)/(vbs_h-vbs_l);
+ return value;
+}
+
+
+void IdVbs::Initialize(double vbs){
+ double vbs_lp,vbs_hp;
+ char filename_l[40];
+ char filename_h[40];
+
+ ifstream vbsf;
+ vbsf.open("vbs_files.txt"); //Fixed name this file must exsit
+ if(!vbsf.is_open()) {
+ cout<<"Failed to open vbs_files.txt \nIts a compulsory file to be there in current directory"<<endl; exit(3);
+ }
+
+ vbsf>>vbs_lp;
+ vbsf>>filename_l;
+
+ bool found=false;
+
+ while(!found || !vbsf.eof()){
+ vbsf>>vbs_hp;
+ vbsf>>filename_h;
+
+ if(vbs>=vbs_lp && vbs<vbs_hp){
+ found=true;
+ break;
+ }
+ vbs_lp=vbs_hp;
+ strcpy(filename_l,filename_h);
+ }
+
+ if(!found){ cout<<"Vgs out of range, This routine does not do Extrapolation"<<endl; exit(1);}
+
+ if( fabs(vbs_l-vbs_hp)<1e-7 ){ // vgs hag gone just one step lower so
+ cc_h=cc_l; // use old value why compute again
+ cc_l.Initialize(filename_l);
+ }
+ else if( fabs(vbs_lp-vbs_h)<1e-7 ){ // vgs hag gone just one step higher so
+ cc_l=cc_h; // use old value why compute again
+ cc_h.Initialize(filename_h);
+ }
+ else{
+ cc_l.Initialize(filename_l);
+ cc_h.Initialize(filename_h);
+ }
+
+ vbs_l=vbs_lp;
+ vbs_h=vbs_hp;
+}
+
+IdVbs::IdVbs(){
+ vbs_l=213.0; //some value not to occur actually
+ vbs_h=-213.0;
+}
+
+IdVbs::~IdVbs(){
+};
+/********************** End ******************************/