00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef INTEGRATOR_H
00024 #define INTEGRATOR_H
00025
00026 #include <stdint.h>
00027
00028 #include "siddefs-fp.h"
00029
00030 namespace reSIDfp
00031 {
00032
00042 class Integrator
00043 {
00044 private:
00045 unsigned int Vddt_Vw_2;
00046 int Vddt, n_snake, x;
00047 int vc;
00048 const unsigned short* vcr_Vg;
00049 const unsigned short* vcr_n_Ids_term;
00050 const int* opamp_rev;
00051
00052 public:
00053 Integrator(const unsigned short* vcr_Vg, const unsigned short* vcr_n_Ids_term,
00054 const int* opamp_rev, int Vddt, int n_snake) :
00055 Vddt_Vw_2(0),
00056 Vddt(Vddt),
00057 n_snake(n_snake),
00058 x(0),
00059 vc(0),
00060 vcr_Vg(vcr_Vg),
00061 vcr_n_Ids_term(vcr_n_Ids_term),
00062 opamp_rev(opamp_rev) {}
00063
00064 void setVw(const int Vw) { Vddt_Vw_2 = (Vddt - Vw) * (Vddt - Vw) >> 1; }
00065
00066 int solve(const int vi);
00067 };
00068
00069 }
00070
00071 #if RESID_INLINING || defined(INTEGRATOR_CPP)
00072
00073 namespace reSIDfp
00074 {
00075
00076 RESID_INLINE
00077 int Integrator::solve(int vi)
00078 {
00079
00080 const int Vgst = Vddt - x;
00081 const int Vgdt = Vddt - vi;
00082
00083 const uint64_t Vgst_2 = (int64_t)Vgst * (int64_t)Vgst;
00084 const uint64_t Vgdt_2 = (int64_t)Vgdt * (int64_t)Vgdt;
00085
00086
00087 const int n_I_snake = n_snake * ((Vgst_2 >> 15) - (Vgdt_2 >> 15));
00088
00089
00090
00091 const int Vg = (int)vcr_Vg[(Vddt_Vw_2 >> 16) + (Vgdt_2 >> 17)];
00092
00093
00094 const int Vgs = Vg > x ? Vg - x : 0;
00095 const int Vgd = Vg > vi ? Vg - vi : 0;
00096
00097
00098 const int n_I_vcr = (int)(vcr_n_Ids_term[Vgs & 0xffff] - vcr_n_Ids_term[Vgd & 0xffff]) << 15;
00099
00100
00101 vc += n_I_snake + n_I_vcr;
00102
00103
00104 x = opamp_rev[((vc >> 15) + (1 << 15)) & 0xffff];
00105
00106
00107 return x - (vc >> 14);
00108 }
00109
00110 }
00111
00112 #endif
00113
00114 #endif