Branch data Line data Source code
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 : 0 : digital::digital () : circuit () {
46 [ # # # # ]: 0 : setVoltageSources (1);
47 : 0 : g = NULL;
48 : 0 : Vout = 0;
49 : 0 : Tdelay = 0;
50 : 0 : delay = false;
51 : 0 : }
52 : :
53 : : // Destructor.
54 : 0 : digital::~digital () {
55 : 0 : freeDigital ();
56 [ # # ][ # # ]: 0 : }
57 : :
58 : : // Reserve space for derivatives.
59 : 0 : void digital::initDigital (void) {
60 [ # # ]: 0 : if (g == NULL) {
61 : 0 : g = (nr_double_t *) malloc ((getSize () - 1) * sizeof (nr_double_t));
62 : : }
63 : 0 : }
64 : :
65 : : // Free space of derivatives if necessary.
66 : 0 : void digital::freeDigital (void) {
67 [ # # ]: 0 : if (g != NULL) {
68 : 0 : free (g);
69 : 0 : g = NULL;
70 : : }
71 : 0 : }
72 : :
73 : : // Returns voltage at given input node.
74 : 0 : nr_double_t digital::getVin (int input) {
75 [ # # ]: 0 : if (delay) {
76 : 0 : return real (getV (NODE_IN1 + input, Tdelay));
77 : : } else {
78 : 0 : return real (getV (NODE_IN1 + input));
79 : : }
80 : : }
81 : :
82 : : // Computes the transfer function for the given input node.
83 : 0 : nr_double_t digital::calcTransferX (int input) {
84 : 0 : nr_double_t v = getPropertyDouble ("V");
85 : 0 : nr_double_t t = getPropertyDouble ("TR");
86 : 0 : return std::tanh (t * (getVin (input) / v - 0.5));
87 : : }
88 : :
89 : : // Computes a slightly modified transfer function.
90 : 0 : nr_double_t digital::calcTransfer (int input) {
91 : 0 : return (1 - GMin) * calcTransferX (input);
92 : : }
93 : :
94 : : // Computes the transfer functions derivative for the given input node.
95 : 0 : nr_double_t digital::calcDerivativeX (int input) {
96 : 0 : nr_double_t v = getPropertyDouble ("V");
97 : 0 : nr_double_t t = getPropertyDouble ("TR");
98 : 0 : nr_double_t x = std::tanh (t * (getVin (input) / v - 0.5));
99 : 0 : return t * (1 - x * x);
100 : : }
101 : :
102 : : // Computes a slightly modified transfer functions derivative.
103 : 0 : nr_double_t digital::calcDerivative (int input) {
104 : 0 : return (1 - GMin) * calcDerivativeX (input);
105 : : }
106 : :
107 : : // Setup constant S-parameter entries.
108 : 0 : void digital::initSP (void) {
109 : 0 : allocMatrixS ();
110 [ # # ]: 0 : setS (NODE_OUT, NODE_OUT, -1);
111 [ # # ]: 0 : for (i = 0; i < getSize () - 1; i++) {
112 [ # # ]: 0 : setS (NODE_IN1 + i, NODE_IN1 + i, +1);
113 : : }
114 : 0 : }
115 : :
116 : : // Setup frequency dependent S-parameter entries.
117 : 0 : void digital::calcSP (nr_double_t frequency) {
118 : 0 : nr_double_t t = getPropertyDouble ("t");
119 [ # # ]: 0 : for (i = 0; i < getSize () - 1; i++) {
120 : : setS (NODE_OUT, NODE_IN1 + i,
121 [ # # ]: 0 : 4.0 * std::polar (g[i], - 2.0 * M_PI * frequency * t));
122 : : }
123 : 0 : }
124 : :
125 : : // Initialize constant MNA entries for DC analysis.
126 : 0 : void digital::initDC (void) {
127 : 0 : initDigital ();
128 : 0 : allocMatrixMNA ();
129 : 0 : delay = false;
130 [ # # ]: 0 : setB (NODE_OUT, VSRC_1, +1);
131 [ # # ]: 0 : setC (VSRC_1, NODE_OUT, -1);
132 [ # # ]: 0 : setE (VSRC_1, 0);
133 : 0 : }
134 : :
135 : : // Computes variable MNA entries during DC analysis.
136 : 0 : void digital::calcDC (void) {
137 : 0 : calcOutput ();
138 : 0 : calcDerivatives ();
139 [ # # ]: 0 : for (i = 0, Veq = 0; i < getSize () - 1; i++) {
140 [ # # ]: 0 : setC (VSRC_1, NODE_IN1 + i, g[i]);
141 : 0 : Veq += g[i] * getVin (i);
142 : : }
143 [ # # ]: 0 : setE (VSRC_1, Veq - Vout);
144 : 0 : }
145 : :
146 : 0 : void digital::calcOperatingPoints (void) {
147 : 0 : calcDerivatives ();
148 : 0 : }
149 : :
150 : : // Initialize constant MNA entries for AC analysis.
151 : 0 : void digital::initAC (void) {
152 : 0 : initDC ();
153 : 0 : }
154 : :
155 : : // Computes frequency dependent MNA entries during AC analysis.
156 : 0 : void digital::calcAC (nr_double_t frequency) {
157 : 0 : nr_double_t t = getPropertyDouble ("t");
158 [ # # ]: 0 : for (i = 0; i < getSize () - 1; i++) {
159 [ # # ]: 0 : setC (VSRC_1, NODE_IN1 + i, std::polar (g[i], - 2.0 * M_PI * frequency * t));
160 : : }
161 : 0 : }
162 : :
163 : : // Initialize transient analysis.
164 : 0 : void digital::initTR (void) {
165 : 0 : nr_double_t t = getPropertyDouble ("t");
166 : 0 : initDC ();
167 : 0 : deleteHistory ();
168 [ # # ]: 0 : if (t > 0.0) {
169 : 0 : delay = true;
170 : 0 : setHistory (true);
171 : 0 : initHistory (t);
172 [ # # ]: 0 : setC (VSRC_1, NODE_OUT, 1);
173 : : }
174 : 0 : }
175 : :
176 : : // Computes MNA entries during transient analysis.
177 : 0 : void digital::calcTR (nr_double_t t) {
178 [ # # ]: 0 : if (delay) {
179 : 0 : Tdelay = t - getPropertyDouble ("t");
180 : 0 : calcOutput ();
181 [ # # ]: 0 : setE (VSRC_1, Vout);
182 : : }
183 : : else {
184 : 0 : calcDC ();
185 : : }
186 : 0 : }
|