Qucs-core  0.0.18
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
digital.cpp
Go to the documentation of this file.
1 /*
2  * digital.cpp - digital base class implementation
3  *
4  * Copyright (C) 2005, 2006, 2009 Stefan Jahn <stefan@lkcc.org>
5  *
6  * This is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2, or (at your option)
9  * any later version.
10  *
11  * This software is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this package; see the file COPYING. If not, write to
18  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
19  * Boston, MA 02110-1301, USA.
20  *
21  * $Id$
22  *
23  */
24 
25 #if HAVE_CONFIG_H
26 # include <config.h>
27 #endif
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <cmath>
32 
33 #include "complex.h"
34 #include "object.h"
35 #include "circuit.h"
36 #include "constants.h"
37 #include "digital.h"
38 
39 #define NODE_OUT 0 /* first node is output node */
40 #define NODE_IN1 1 /* input nodes start here */
41 
42 using namespace qucs;
43 
44 // Constructor.
45 digital::digital () : circuit () {
47  g = NULL;
48  Vout = 0;
49  Tdelay = 0;
50  delay = false;
51 }
52 
53 // Destructor.
55  freeDigital ();
56 }
57 
58 // Reserve space for derivatives.
59 void digital::initDigital (void) {
60  if (g == NULL) {
61  g = (nr_double_t *) malloc ((getSize () - 1) * sizeof (nr_double_t));
62  }
63 }
64 
65 // Free space of derivatives if necessary.
66 void digital::freeDigital (void) {
67  if (g != NULL) {
68  free (g);
69  g = NULL;
70  }
71 }
72 
73 // Returns voltage at given input node.
74 nr_double_t digital::getVin (int input) {
75  if (delay) {
76  return real (getV (NODE_IN1 + input, Tdelay));
77  } else {
78  return real (getV (NODE_IN1 + input));
79  }
80 }
81 
82 // Computes the transfer function for the given input node.
83 nr_double_t digital::calcTransferX (int input) {
84  nr_double_t v = getPropertyDouble ("V");
85  nr_double_t t = getPropertyDouble ("TR");
86  return std::tanh (t * (getVin (input) / v - 0.5));
87 }
88 
89 // Computes a slightly modified transfer function.
90 nr_double_t digital::calcTransfer (int input) {
91  return (1 - GMin) * calcTransferX (input);
92 }
93 
94 // Computes the transfer functions derivative for the given input node.
95 nr_double_t digital::calcDerivativeX (int input) {
96  nr_double_t v = getPropertyDouble ("V");
97  nr_double_t t = getPropertyDouble ("TR");
98  nr_double_t x = std::tanh (t * (getVin (input) / v - 0.5));
99  return t * (1 - x * x);
100 }
101 
102 // Computes a slightly modified transfer functions derivative.
103 nr_double_t digital::calcDerivative (int input) {
104  return (1 - GMin) * calcDerivativeX (input);
105 }
106 
107 // Setup constant S-parameter entries.
108 void digital::initSP (void) {
109  allocMatrixS ();
110  setS (NODE_OUT, NODE_OUT, -1);
111  for (i = 0; i < getSize () - 1; i++) {
112  setS (NODE_IN1 + i, NODE_IN1 + i, +1);
113  }
114 }
115 
116 // Setup frequency dependent S-parameter entries.
117 void digital::calcSP (nr_double_t frequency) {
118  nr_double_t t = getPropertyDouble ("t");
119  for (i = 0; i < getSize () - 1; i++) {
120  setS (NODE_OUT, NODE_IN1 + i,
121  4.0 * std::polar (g[i], - 2.0 * M_PI * frequency * t));
122  }
123 }
124 
125 // Initialize constant MNA entries for DC analysis.
126 void digital::initDC (void) {
127  initDigital ();
128  allocMatrixMNA ();
129  delay = false;
130  setB (NODE_OUT, VSRC_1, +1);
131  setC (VSRC_1, NODE_OUT, -1);
132  setE (VSRC_1, 0);
133 }
134 
135 // Computes variable MNA entries during DC analysis.
136 void digital::calcDC (void) {
137  calcOutput ();
138  calcDerivatives ();
139  for (i = 0, Veq = 0; i < getSize () - 1; i++) {
140  setC (VSRC_1, NODE_IN1 + i, g[i]);
141  Veq += g[i] * getVin (i);
142  }
143  setE (VSRC_1, Veq - Vout);
144 }
145 
147  calcDerivatives ();
148 }
149 
150 // Initialize constant MNA entries for AC analysis.
151 void digital::initAC (void) {
152  initDC ();
153 }
154 
155 // Computes frequency dependent MNA entries during AC analysis.
156 void digital::calcAC (nr_double_t frequency) {
157  nr_double_t t = getPropertyDouble ("t");
158  for (i = 0; i < getSize () - 1; i++) {
159  setC (VSRC_1, NODE_IN1 + i, std::polar (g[i], - 2.0 * M_PI * frequency * t));
160  }
161 }
162 
163 // Initialize transient analysis.
164 void digital::initTR (void) {
165  nr_double_t t = getPropertyDouble ("t");
166  initDC ();
167  deleteHistory ();
168  if (t > 0.0) {
169  delay = true;
170  setHistory (true);
171  initHistory (t);
172  setC (VSRC_1, NODE_OUT, 1);
173  }
174 }
175 
176 // Computes MNA entries during transient analysis.
177 void digital::calcTR (nr_double_t t) {
178  if (delay) {
179  Tdelay = t - getPropertyDouble ("t");
180  calcOutput ();
181  setE (VSRC_1, Vout);
182  }
183  else {
184  calcDC ();
185  }
186 }
void calcDC(void)
Definition: digital.cpp:136
void setHistory(bool h)
Definition: circuit.h:213
digital()
Definition: digital.cpp:45
matrix real(matrix a)
Real part matrix.
Definition: matrix.cpp:568
void initDigital(void)
Definition: digital.cpp:59
void calcSP(nr_double_t)
Definition: digital.cpp:117
void initDC(void)
Definition: digital.cpp:126
nr_double_t getPropertyDouble(const char *)
Definition: object.cpp:176
virtual void calcDerivatives(void)
Definition: digital.h:45
t
Definition: parse_vcd.y:290
~digital()
Definition: digital.cpp:54
virtual void calcOutput(void)
Definition: digital.h:44
void setVoltageSources(int)
Definition: circuit.cpp:607
nr_double_t Vout
Definition: digital.h:54
Global physical constants header file.
void setB(int, int, nr_complex_t)
Definition: circuit.cpp:349
void allocMatrixS(void)
Definition: circuit.cpp:251
void initSP(void)
placehoder for S-Parameter initialisation function
Definition: digital.cpp:108
int getSize(void)
Get the number of ports the circuit element has.
Definition: circuit.h:143
void freeDigital(void)
Definition: digital.cpp:66
#define VSRC_1
Definition: circuit.h:40
void calcAC(nr_double_t)
Definition: digital.cpp:156
nr_double_t Tdelay
Definition: digital.h:54
void calcTR(nr_double_t)
Definition: digital.cpp:177
nr_complex_t tanh(const nr_complex_t z)
Compute complex hyperbolic tangent.
Definition: complex.cpp:153
nr_double_t calcDerivative(int)
Definition: digital.cpp:103
void deleteHistory(void)
Definition: circuit.cpp:886
free($1)
nr_double_t getVin(int)
Definition: digital.cpp:74
void setE(int, nr_complex_t)
Definition: circuit.cpp:385
x
Definition: parse_mdl.y:498
#define M_PI
Archimedes' constant ( )
Definition: consts.h:47
#define NODE_OUT
Definition: digital.cpp:39
int i
Definition: digital.h:55
The circuit class header file.
void initAC(void)
Definition: digital.cpp:151
#define NODE_IN1
Definition: digital.cpp:40
void calcOperatingPoints(void)
Definition: digital.cpp:146
v
Definition: parse_zvr.y:141
void allocMatrixMNA(void)
Definition: circuit.cpp:267
nr_double_t calcTransfer(int)
Definition: digital.cpp:90
void initTR(void)
Definition: digital.cpp:164
#define GMin
Gmin.
Definition: constants.h:104
nr_double_t getV(int, nr_double_t)
Definition: circuit.cpp:941
nr_double_t calcTransferX(int)
Definition: digital.cpp:83
void setS(int, int, nr_complex_t)
Definition: circuit.cpp:587
nr_complex_t polar(const nr_double_t mag, const nr_double_t ang)
Construct a complex number using polar notation.
Definition: complex.cpp:551
bool delay
Definition: digital.h:56
void setC(int, int, nr_complex_t)
Definition: circuit.cpp:361
void initHistory(nr_double_t)
Definition: circuit.cpp:869
nr_double_t calcDerivativeX(int)
Definition: digital.cpp:95
nr_double_t * g
Definition: digital.h:53
nr_double_t Veq
Definition: digital.h:54