1 /*
2    Copyright (C) 2017 Roy R Rankin
3 
4 This file is part of the libgpsim library of gpsim
5 
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10 
11 This library 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 GNU
14 Lesser General Public License for more details.
15 
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, see
18 <http://www.gnu.org/licenses/lgpl-2.1.html>.
19 
20 COMPLEMENTARY WAVEFORM GENERATOR (CWG) MODULE
21 
22 */
23 
24 #ifndef SRC_CWG_H_
25 #define SRC_CWG_H_
26 
27 #include <string>
28 
29 #include "registers.h"
30 #include "trigger.h"
31 #include "ioports.h"
32 
33 class CWG;
34 class CWGSignalSource;
35 class FLTSignalSink;
36 class PinModule;
37 class Processor;
38 class TristateControl;
39 
40 class CWGxCON0 : public sfr_register
41 {
42 public:
43     CWGxCON0(CWG *pt, Processor *pCpu, const char *pName, const char *pDesc);
44 
45     virtual void put(unsigned int new_value);
set_con0_mask(unsigned int mask)46     void set_con0_mask(unsigned int mask) { con0_mask = mask; }
47 
48 private:
49     CWG *pt_cwg;
50     unsigned int con0_mask;
51 };
52 
53 class CWGxCON1 : public sfr_register
54 {
55 public:
56     CWGxCON1(CWG *pt, Processor *pCpu, const char *pName, const char *pDesc);
57 
58     virtual void put(unsigned int new_value);
set_con1_mask(unsigned int mask)59     void set_con1_mask(unsigned int mask) { con1_mask = mask; }
60 
61 private:
62     CWG *pt_cwg;
63     unsigned int con1_mask;
64 };
65 
66 class CWGxCON2 : public sfr_register
67 {
68 public:
69     CWGxCON2(CWG *pt, Processor *pCpu, const char *pName, const char *pDesc);
70 
71     virtual void put(unsigned int new_value);
72 
73 private:
74     CWG *pt_cwg;
75     unsigned int con2_mask;
76 };
77 
78 class CWGxDBR : public sfr_register, public TriggerObject
79 {
80 public:
81     enum
82     {
83         CWGxDBR0 = 1<<0,
84         CWGxDBR1 = 1<<1,
85         CWGxDBR2 = 1<<2,
86         CWGxDBR3 = 1<<3,
87         CWGxDBR4 = 1<<4,
88         CWGxDBR5 = 1<<5
89     };
90     CWGxDBR(CWG *pt, Processor *pCpu, const char *pName, const char *pDesc);
91 
92     virtual void callback();
93     virtual void callback_print();
94     void new_edge(bool level, double mult);
95     void kill_callback();
96 
97 private:
98     CWG *pt_cwg;
99     guint64  future_cycle = 0;
100     bool     next_level = false;
101 };
102 class CWGxDBF : public sfr_register, public TriggerObject
103 {
104 public:
105     enum
106     {
107         CWGxDBF0 = 1<<0,
108         CWGxDBF1 = 1<<1,
109         CWGxDBF2 = 1<<2,
110         CWGxDBF3 = 1<<3,
111         CWGxDBF4 = 1<<4,
112         CWGxDBF5 = 1<<5
113     };
114     CWGxDBF(CWG *pt, Processor *pCpu, const char *pName, const char *pDesc);
115 
116     virtual void callback();
117     virtual void callback_print();
118     void new_edge(bool level, double mult);
119     void kill_callback();
120 
121 private:
122     CWG *pt_cwg;
123     guint64  future_cycle = 0;
124     bool     next_level = false;
125 };
126 
127 // Complementary waveform generator - 4 clock inputs
128 class CWG
129 {
130 public:
131     enum
132     {
133         //CWG1CON0
134         GxCS0  = 1<<0,
135         GxPOLA = 1<<3,
136         GxPOLB = 1<<4,
137         GxOEA  = 1<<5,
138         GxOEB  = 1<<6,
139         GxEN   = 1<<7,
140         //CWG1CON1
141         GxIS0    = 1<<0,
142         GxIS1    = 1<<1,
143         GxIS2    = 1<<2,
144         GxASDLA0 = 1<<4,
145         GxASDLA1 = 1<<5,
146         GxASDLB0 = 1<<6,
147         GxASDLB1 = 1<<7,
148         //CWG1CON2
149         GxASDFLT = 1<<0,
150         GxASDCLC1 = 1<<1,
151         GxARSEN  = 1<<6,
152         GxASE    = 1<<7
153     };
154 
155     CWGxCON0 cwg1con0;
156     CWGxCON1 cwg1con1;
157     CWGxCON2 cwg1con2;
158     CWGxDBF  cwg1dbf;
159     CWGxDBR  cwg1dbr;
160 
161     explicit CWG(Processor *pCpu);
162     ~CWG();
163 
164     void set_IOpins(PinModule *, PinModule *, PinModule *);
165     void oeA();
166     void oeB();
167     void cwg_con0(unsigned int);
168     void cwg_con1(unsigned int);
169     void cwg_con2(unsigned int);
170     void releasePin(PinModule *pin);
171     void releasePinSource(PinModule *pin);
172     virtual void out_pwm(bool level, char index);
173     virtual void out_NCO(bool level);
174     virtual void out_CLC(bool level, char index=1);
175     void input_source(bool level);
176     void set_outA(bool level);
177     void set_outB(bool level);
178     void autoShutEvent(bool on);
179     void enableAutoShutPin(bool on);
180     virtual void setState(char);
181 
182 protected:
183     bool       pwm_state[4];
184     bool	     clc_state[4];
185     bool	     nco_state = false;
186     unsigned int con0_value = 0;
187     unsigned int con1_value = 0;
188     unsigned int con2_value = 0;
189     bool         shutdown_active = false;
190 
191 private:
192     std::string     Agui;
193     std::string     Bgui;
194     std::string     FLTgui;
195     Processor       *cpu;
196     PinModule       *pinA = nullptr;
197     PinModule       *pinB = nullptr;
198     PinModule       *pinFLT = nullptr;
199     TristateControl *Atri = nullptr;
200     TristateControl *Btri = nullptr;
201     CWGSignalSource *Asrc = nullptr;
202     CWGSignalSource *Bsrc = nullptr;
203     FLTSignalSink   *FLTsink = nullptr;
204     bool             pinAactive = false;
205     bool             pinBactive = false;
206     bool             srcAactive = false;
207     bool             srcBactive = false;
208     bool             cwg_enabled = false;
209     bool             OEA_state = false;
210     bool             OEB_state = false;
211     bool             active_next_edge = false;
212     bool	     FLTstate = false;
213 };
214 
215 class CWG4 : public CWG
216 {
217 public:
218     CWG4(Processor *pCpu);
219     virtual void out_pwm(bool level, char index);
220     virtual void out_NCO(bool level);
221 };
222 class COG;
223 
224 // COGxCON0: COG CONTROL REGISTER 0
225 class COGxCON0: public sfr_register
226 {
227 public:
228     COGxCON0(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
229     virtual void put(unsigned int new_value);
set_con0_mask(unsigned int _mask)230     void set_con0_mask(unsigned int _mask) { mask = _mask; }
231 private:
232     COG *pt_cog;
233     unsigned int mask;
234 };
235 
236 // COGxCON1: COG CONTROL REGISTER 1
237 class COGxCON1: public sfr_register
238 {
239 public:
240     COGxCON1(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
241 
242     virtual void put(unsigned int new_value);
set_con1_mask(unsigned int _mask)243     void set_con1_mask(unsigned int _mask) { mask = _mask; }
244 private:
245     COG *pt_cog;
246     unsigned int mask;
247 };
248 
249 // COGxRIS: COG RISING EVENT INPUT SELECTION REGISTER
250 class COGxRIS: public sfr_register
251 {
252 public:
253     COGxRIS(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
254     virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)255     void set_mask(unsigned int _mask) { mask = _mask; }
256 private:
257     COG *pt_cog;
258     unsigned int mask;
259 };
260 
261 // COGxRSIM: COG RISING EVENT SOURCE INPUT MODE REGISTE
262 class COGxRSIM: public sfr_register
263 {
264 public:
265     COGxRSIM(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
266 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)267     void set_mask(unsigned int _mask) { mask = _mask; }
268 private:
269     COG *pt_cog;
270     unsigned int mask;
271 };
272 
273 // COGxFIS: COG FALLING EVENT INPUT SELECTION REGISTER
274 class COGxFIS: public sfr_register
275 {
276 public:
277     COGxFIS(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
278     virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)279     void set_mask(unsigned int _mask) { mask = _mask; }
280 private:
281     COG *pt_cog;
282     unsigned int mask;
283 };
284 
285 // COGxFSIM: COG FALLING EVENT SOURCE INPUT MODE REGISTER
286 class COGxFSIM: public sfr_register
287 {
288 public:
289     COGxFSIM(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
290 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)291     void set_mask(unsigned int _mask) { mask = _mask; }
292 private:
293     COG *pt_cog;
294     unsigned int mask;
295 };
296 
297 // COGxASD0: COG AUTO-SHUTDOWN CONTROL REGISTER 0
298 class COGxASD0: public sfr_register
299 {
300 public:
301     COGxASD0(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
302     virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)303     void set_mask(unsigned int _mask) { mask = _mask; }
304 private:
305     COG *pt_cog;
306     unsigned int mask;
307 };
308 
309 
310 // COGxASD1: COG AUTO-SHUTDOWN CONTROL REGISTER 1
311 class COGxASD1: public sfr_register
312 {
313 public:
314     COGxASD1(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
315 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)316     void set_mask(unsigned int _mask) { mask = _mask; }
317 private:
318     COG *pt_cog;
319     unsigned int mask;
320 };
321 
322 // COGxSTR: COG STEERING CONTROL REGISTER 1
323 class COGxSTR: public sfr_register
324 {
325 public:
326     COGxSTR(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
327     virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)328     void set_mask(unsigned int _mask) { mask = _mask; }
329 private:
330     COG *pt_cog;
331     unsigned int mask;
332 };
333 
334 // COGxDBR: COG RISING EVENT DEAD-BAND COUNT REGISTER
335 class COGxDBR: public sfr_register
336 {
337 public:
338     COGxDBR(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
339 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)340     void set_mask(unsigned int _mask) { mask = _mask; }
341 private:
342     COG *pt_cog;
343     unsigned int mask;
344 };
345 
346 // COGxDBF: COG FALLING EVENT DEAD-BAND COUNT REGISTER
347 class COGxDBF: public sfr_register
348 {
349 public:
350     COGxDBF(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
351 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)352     void set_mask(unsigned int _mask) { mask = _mask; }
353 private:
354     COG *pt_cog;
355     unsigned int mask;
356 };
357 
358 // COGxBLKR: COG RISING EVENT BLANKING COUNT REGISTER
359 class COGxBLKR: public sfr_register
360 {
361 public:
362     COGxBLKR(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
363 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)364     void set_mask(unsigned int _mask) { mask = _mask; }
365 private:
366     COG *pt_cog;
367     unsigned int mask;
368 };
369 
370 // COGxBLKF: COG FALLING EVENT BLANKING COUNT REGISTER
371 class COGxBLKF: public sfr_register
372 {
373 public:
374     COGxBLKF(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
375 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)376     void set_mask(unsigned int _mask) { mask = _mask; }
377 private:
378     COG *pt_cog;
379     unsigned int mask;
380 };
381 
382 // COGxPHR: COG RISING EDGE PHASE DELAY COUNT REGISTER
383 class COGxPHR: public sfr_register
384 {
385 public:
386     COGxPHR(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
387 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)388     void set_mask(unsigned int _mask) { mask = _mask; }
389 private:
390     COG *pt_cog;
391     unsigned int mask;
392 };
393 
394 // COGxPHF: COG FALLING EDGE PHASE DELAY COUNT REGISTER
395 class COGxPHF: public sfr_register
396 {
397 public:
398     COGxPHF(COG *pt, Processor *pCpu, const char *pName, const char *pDesc);
399 //	virtual void put(unsigned int new_value);
set_mask(unsigned int _mask)400     void set_mask(unsigned int _mask) { mask = _mask; }
401 private:
402     COG *pt_cog;
403     unsigned int mask;
404 };
405 
406 class COGSignalSource;
407 class COGTristate;
408 class COGSink;
409 
410 class COG: public apfpin, public TriggerObject
411 {
412 public:
413 
414 
415     COG(Processor *pCpu, const char *pName = "COG");
416     ~COG();
417     void input_event(int index, bool level);
418     void drive_bridge(int level, int state);
419     void shutdown_bridge();
420     void cog_con0(unsigned int);
421     void cog_con1(unsigned int);
422     void cog_str(unsigned int);
423     void cog_asd0(unsigned int, unsigned int);
424     void set_inputPin();
425     void set_outputPins();
426     virtual void setIOpin(PinModule * _pin, int i);
set_pinIN(PinModule * _pinIN)427     void set_pinIN(PinModule * _pinIN) { pinIN = _pinIN;}
428     virtual void out_ccp(bool level, char index);
429     virtual void out_pwm(bool level, char index);
430     virtual void out_clc(bool level, char index);
431     virtual void out_Cx(bool level, char index);
432     virtual void cogx_in(char newState);
433     void output_pin(int pin, bool set);
releasePins(int index)434     void releasePins(int index) {printf("releasePins %d\n", index);}
435     virtual void callback();
436 
437     enum
438     {
439         //COGxCON0
440         GxEN       = 1<<7,
441         GxLD       = 1<<6,    // COGx Load Buffers bit
442         GxCS_MASK  = 0x18,    //COGx Clock Selection bits
443         GxCS_SHIFT = 3,
444         GxMD_MASK  = 0x7,     // COGx Mode Selection bits
445 
446         //COGxCON1
447         GxRDBS   = 1<<7,  // COGx Rising Event Dead-band Timing Source
448         GxFDBS   = 1<<6,  // COGx Falling Event Dead-band Timing Source select bit
449         GxPOLD   = 1<<3,  // COGxD Output Polarity Control bit
450         GxPOLC   = 1<<2,  // COGxC Output Polarity Control bit
451         GxPOLB   = 1<<1,  // COGxB Output Polarity Control bit
452         GxPOLA   = 1<<0,  // COGxA Output Polarity Control bit
453 
454         //COGxRIS: COG RISING EVENT INPUT SELECTION REGISTER
455         //COGxRSIM: COG RISING EVENT SOURCE INPUT MODE REGISTER
456         //COGxFIS: COG FALLING EVENT INPUT SELECTION REGISTER
457         //COGxFSIM: COG FALLING EVENT SOURCE INPUT MODE REGISTER
458         //COGxASD0: COG AUTO-SHUTDOWN CONTROL REGISTER 0
459         GxASE    = 1<<7,  // Auto-Shutdown Event Status bit
460         GxARSEN  = 1<<6,  // Auto-Restart Enable bit
461         GxASDBD_MSK = 0x30, // COGxB and COGxD Auto-shutdown Override Level
462         GxASDBD_SFT = 4,
463         GxASDAC_MSK = 0xc0, // COGxA and COGxC Auto-shutdown Override Level
464         GxASDAC_SFT = 2,
465 
466         // COGxASD1: COG AUTO-SHUTDOWN CONTROL REGISTER 1
467         GxAS3E   = 1<<3,  // COGx Auto-shutdown Source Enable bit 3
468         GxAS2E   = 1<<2,  // COGx Auto-shutdown Source Enable bit 2
469         GxAS1E   = 1<<1,  // COGx Auto-shutdown Source Enable bit 1
470         GxAS0E   = 1<<0,  // COGx Auto-shutdown Source Enable bit 0
471 
472         //COGxSTR: COG STEERING CONTROL REGISTER 1
473         GxSDATD  = 1<<7,  // COGxD Static Output Data bit
474         GxSDATC  = 1<<6,  // COGxC Static Output Data bit
475         GxSDATB  = 1<<5,  // COGxB Static Output Data bit
476         GxSDATA  = 1<<4,  // COGxA Static Output Data bit
477         GxSSTRD  = 1<<3,  // COGxD Steering Control bit
478         GxSSTRC  = 1<<2,  // COGxC Steering Control bit
479         GxSSTRB  = 1<<1,  // COGxB Steering Control bit
480         GxSSTRA  = 1<<0,  // COGxA Steering Control bit
481 
482         // COGxDBR: COG RISING EVENT DEAD-BAND COUNT REGISTER
483         // COGxDBF: COG FALLING EVENT DEAD-BAND COUNT REGISTER
484         // COGxBLKR: COG RISING EVENT BLANKING COUNT REGISTER
485         // COGxBLKF: COG FALLING EVENT BLANKING COUNT REGISTER
486         // COGxPHR: COG RISING EDGE PHASE DELAY COUNT REGISTER
487         // COGxPHF: COG FALLING EDGE PHASE DELAY COUNT REGISTER
488     };
489 
490 #define FIRST_STATE 0
491 #define PHASE_STATE 1
492 #define LAST_STATE  2
493 
494 #define GXASE (1<<7)
495 
496     COGxCON0 cogxcon0;
497     COGxCON1 cogxcon1;
498     COGxRIS  cogxris;
499     COGxRSIM cogxrsim;
500     COGxFIS  cogxfis;
501     COGxFSIM cogxfsim;
502     COGxASD0 cogxasd0;
503     COGxASD1 cogxasd1;
504     COGxSTR  cogxstr;
505     COGxDBR  cogxdbr;
506     COGxDBF  cogxdbf;
507     COGxBLKR cogxblkr;
508     COGxBLKF cogxblkf;
509     COGxPHR  cogxphr;
510     COGxPHF  cogxphf;
511 
512 private:
513     Processor       *cpu;
514     std::string	    name_str;
515     PinModule       *m_PinModule[4];	// Output Pins
516     COGSignalSource *m_source[4];
517     bool            source_active[4];
518     PinModule       *pinIN;     // Input source
519     COGSink	    *cogSink;
520     COGTristate     *m_tristate;
521     guint64	    set_cycle;
522     guint64	    reset_cycle;
523     guint64	    phase_cycle;
524     bool            delay_source0, delay_source1;
525     bool            bridge_shutdown;
name()526     std::string	    name() { return name_str;}
527     bool	    input_set;
528     bool	    input_clear;
529     bool	    full_forward;
530     bool	    push_pull_level;
531     bool	    active_high[4];
532     bool	    steer_ctl[4];
533     guint8	    auto_shut_src;
534 };
535 #endif // SRC_CWG_h__
536 
537