Die Implementierung von TrÀgheitsalgorithmen am Beispiel der logischen Modellierung digitaler Schaltungen

1. Einleitung


Wir fahren mit dem zweiten Teil des Themas fort, das verschachtelten Automaten gewidmet ist. Im ersten Teil untersuchten wir rekursive Algorithmen, deren Implementierung mit einem Modell verschachtelter Automaten und der Verbindung von OOP-Funktionen nicht so schwierig war. Die Möglichkeiten verschachtelter Automaten sind jedoch nicht darauf beschrĂ€nkt. Bei der Beschreibung des Steuerungsmodells von Automatenprogrammen wurden TrĂ€gheitsalgorithmen ermittelt, die ebenfalls auf der Idee der Einbettung von Automaten beruhen. TrĂ€gheitsalgorithmen sind im Rahmen des ĂŒblichen Blockdiagramms des Rechenmodells, das keine RĂŒckkehr der Kontrolle zu dem Punkt vor dem Unterprogrammaufruf vorsieht, schwer vorstellbar. Aber ich muss sagen, dass herkömmliche Automaten auch die Abschaffung von ÜbergĂ€ngen "on the fly" vorsehen. FĂŒr Automaten ist dies jedoch nicht nur vorstellbar, sondern auch umsetzbar.

TrĂ€gheitsalgorithmen und logische Modellierung von Themen im Zusammenhang mit digitalen Schaltkreisen. Und nicht so sehr, weil die TrĂ€gheitsverzögerung der betrachteten Klasse von Algorithmen den Namen gab, sondern wie viel die Bedeutung der verzögerten Aktionen der TrĂ€gheitsverzögerung, die auf die Bedeutung ihrer Arbeit ĂŒbertragen wurde. Obwohl es natĂŒrlich nicht der Name ist. In UML werden Ă€hnliche Algorithmen unter Verwendung des Konzepts des Verlaufsstatus implementiert. Die Analogie ist unkompliziert, obwohl die Modellierung digitaler Schaltungen in UML in der Regel nicht in Frage kommt. Es ist nur so, dass die Situationen bei der RĂŒckkehr zum Ausgangspunkt, wenn etwas dazu zwingt, die natĂŒrlichsten zu sein scheinen. Beispiele sind die Verweigerung des Ticketkaufs, die Stornierung von BankgeschĂ€ften / -transaktionen, die Trennung einer Netzwerkverbindung usw. usw. Am Ende, wie in UML angegeben,Ohne die Verwendung historischer ZustĂ€nde wĂ€re die Implementierung solcher Algorithmen nicht so „schön“ [1].

Das Thema der logischen Modellierung digitaler Schaltungen ist an sich umfangreich und interessant. Und eine neue Lesung tut ihr nicht weh. Wie wir sehen werden, kann die automatische Programmiertechnologie eine noch bessere Möglichkeit bieten, digitale Schaltungen zu beschreiben, zu implementieren und logisch zu modellieren. Wir werden dies trotzdem kennenlernen und das Hauptziel verfolgen - eine interessante, nĂŒtzliche und schließlich nur eine schöne Klasse von Algorithmen zu betrachten, die fĂŒr Automaten natĂŒrlich ist, aber in anderen Rechenmodellen nur schwer zu implementieren ist.

2. Logische Modellierung digitaler Schaltungen


In der Literatur werden normalerweise zwei Methoden zur Modellierung digitaler Schaltkreise betrachtet - Zusammenstellung und Ereignis. Die Kompilierung ist in ihren Möglichkeiten begrenzt, weil berĂŒcksichtigt keine Elementverzögerungen, erfordert die Einstufung von Elementen und das Brechen von RĂŒckmeldungen [2]. Die Ereignismethode unterliegt keinen solchen EinschrĂ€nkungen und basiert auf der Verfolgung von Ereignissen, die mit Änderungen der Signalwerte innerhalb der Schaltung verbunden sind. Wir werden die Kompilierung nicht in Betracht ziehen, sondern uns darauf konzentrieren, das Ereignis mit der im Rahmen der Möglichkeiten der automatischen Programmierung implementierten Methode zu vergleichen, die wir dementsprechend auf automatische Weise weiter aufrufen werden.

Nehmen Sie als Beispiel die Schaltung aus [2], die in Abb. 1. Diagramme ihrer Arbeit aus der Quelle sind in Abb. 1 dargestellt. 2. Es werden zwei Optionen in Betracht gezogen: mit einer einzelnen Verzögerung, wenn die Logikelemente der Schaltung dieselbe Verzögerung haben, und mit einer verteilten Verzögerung, wenn die Elemente B und E eine doppelt so lange Verzögerung haben wie die ĂŒbrigen Schaltungselemente.
Bild

Feige. 1. Ein Beispiel fĂŒr eine Schaltung.

Bild

Feige. 2. Beispiele fĂŒr die Modellierung: a - eine einzelne Verzögerung; b - verteilte Verzögerung.

Mit der automatischen Simulationsmethode mĂŒssen Sie nicht einmal etwas erfinden, weil Es ist nicht erforderlich, eine ausreichend spezifische Sprache fĂŒr die Beschreibung einer Schaltung und von Strukturen zu erstellen, die Schaltungsbeziehungen implementieren, und es sind keine ausreichend spezifischen Algorithmen fĂŒr die Erkennung von Ereignissen bei der Modellierung einer Schaltung erforderlich, die dann als Grundlage fĂŒr die Erstellung von Flussdiagrammen einer Schaltung dienen (eine Beschreibung beider finden Sie in [2]). )

Bei Automaten werden die fĂŒr die Automatentechnologie fĂŒr die Programmgestaltung ĂŒblichen logischen Elementmodelle erstellt, die in der Logical Element Library (BLE) enthalten sind. Auf der Basis dieser Bibliothek wird dann ein Satz paralleler Automatenprozesse entsprechend der Anzahl der Schaltungselemente erstellt, zwischen denen die Verbindungen unter Verwendung der Eingabe- / AusgabekanĂ€le logischer Elementmodelle angezeigt werden (in der VKPA-Umgebung sind lokale Prozessvariablen hĂ€ufig ausreichend). Zusammenfassend wird das Schaltungsmodell durch Prozessgeneratoren von Eingangssignalen und Prozesse zum Anzeigen von Signaldiagrammen ergĂ€nzt.

Die Simulationsergebnisse des betrachteten Beispiels in der VKPa-Umgebung, die in Abb. 3 stimmen vollstĂ€ndig mit den Diagrammen in Fig. 3 ĂŒberein. 2. Es war zwar nicht sofort möglich, einen solchen Zufall zu erreichen. Und das nicht wegen Problemen mit den Modellen, sondern weil die „wissenschaftliche Auswahlmethode“ tatsĂ€chlich die Dauer der Eingangssignale berechnen musste, was, wie sich herausstellte, einen erheblichen Einfluss hat. Aber in [2] wurde weder darĂŒber noch ĂŒber die Parameter der Eingangssignale ein Wort gesagt. Die vollstĂ€ndige Übereinstimmung wurde erreicht, indem herausgefunden wurde, dass 1) eine Dauer erforderlich ist, die dem Dreifachen der Verzögerung entspricht, und 2) das Signal (b) sich in Bezug auf das Signal (a) fĂŒr eine Zeit verschieben sollte, die einer einzelnen Verzögerung entspricht. Um dieses Problem zu erklĂ€ren, siehe Abb. Abbildung 4 zeigt die Signaldiagramme fĂŒr unterschiedliche Dauern der Eingangssignale (und dies ohne BerĂŒcksichtigung ihrer Verschiebung).

Bild

Feige. 3. Die Simulation ergibt VKPa: a - eine einzelne Verzögerung; b - verteilte Verzögerung.

Bild

Feige. 4. Simulationsergebnisse mit unterschiedlichen Eingangssignaldauern

Betrachten Sie ein weiteres Beispiel fĂŒr eine Schaltung aus derselben Quelle [2]. Das Schema und die Zeitdiagramme der Arbeit sind in Abb. 2 dargestellt. 5. Im Rahmen der Ereignismethode waren zur „Berechnung“ des Zeitdiagramms 20 Simulationsschritte erforderlich (weitere Einzelheiten siehe [2]). Wie dort angegeben, sind jedoch ein noch komplexerer Algorithmus und dementsprechend eine noch grĂ¶ĂŸere Anzahl von Schritten erforderlich, wenn der TrĂ€gheitstyp der Verzögerungen gewĂ€hlt wird. In unserem Fall (im Fall der automatischen Modellierungsmethode) mit dem vorherigen Modell benötigen wir „20 Klicks“ mit der Maus, um zum Diagramm in Abb. 1 zu gelangen. 5, Entfernen unnötiger Elemente der ursprĂŒnglichen Schaltung. Die Ergebnisse der in VKPa erhaltenen Schaltungssimulation sind in Abb. 1 dargestellt. 6.

Bild

Feige. 5. Ein Beispiel fĂŒr eine Schaltung und ihr Zeitdiagramm.

ZusĂ€tzlich ist das Diagramm in Abb. 5 haben wir parallel zum Element ODER Element I hinzugefĂŒgt. Graph d in Abb. 6 zeigt seinen Betrieb fĂŒr den Fall einer einzelnen Verzögerung an. Wenn wir eine große Verzögerung einstellen und den TrĂ€gheitstyp der Verzögerung einstellen, wird der Graph d zu einer geraden Linie. Daher wird das And-Element mit einer TrĂ€gheitsverzögerung, die grĂ¶ĂŸer als ein einzelner Wert ist, den an seinen EingĂ€ngen durch eine Kombination dieser Eingangssignale a und b erzeugten Impuls nicht verfehlen. Beachten Sie, dass das Manipulieren des Verzögerungstyps nur fĂŒr Elemente sinnvoll ist, deren Verzögerung grĂ¶ĂŸer als eins ist.

Bild

Feige. 6. Modellierung der Schaltung in Abb. 5 und das Element Und (d).

3. Implementierung von Logikelementen


Im allgemeinen Fall kann jedes logische Element als Reihenschaltung zweier Blöcke dargestellt werden (siehe Abb. 7) - ein ideales logisches Element ohne Verzögerung und ein Block, der als Ausbreitungsverzögerung (Transportverzögerung) oder TrÀgheitsverzögerung betrachtet werden kann [2].

Bild

Feige. 7. Modell mit verzögerter Logikelemente.

Ein ideales logisches Element lĂ€sst sich sehr einfach durch eine normale logische Funktion implementieren, und das Verzögerungsblockmodell kann in Form eines Automatenmodells dargestellt werden - eines universellen Modells, das Transport und TrĂ€gheitsverzögerung umfasst. Ein Modell einer solchen universellen Verzögerung ist in Abb. 1 dargestellt. 8 und Modelle von verschachtelten Automaten dafĂŒr sind in Fig. 8 gezeigt. 9. Ihre Implementierung in C ++ und als Teil der automatisierten Programmiertechnologie ist in Listing 1 dargestellt.

Bild

Feige. 8. Das Modell der universellen Verzögerung.

Bild

Feige. 9. Modelle verschachtelter Automaten fĂŒr universelle Verzögerung.

Die Maschinen in Abb. 8 und Abb. 9 sind gemischte Mili-Moore-Sturmgewehre. Der Betrieb des Hauptautomaten in Abb. 8. beginnt mit dem Erstellen lokaler Variablen und dem Initialisieren der Referenzen in Aktion y12 (das PrĂ€dikat x12 ĂŒberprĂŒft dies alles). Der Zwischenzustand "ss" ist erforderlich, damit das PrĂ€dikat x3 korrekt funktioniert, das eine VerknĂŒpfung zu einer Eingabevariablen hat, die möglicherweise nicht initialisiert wird. Ab dem Zustand "ss" wechselt das Modell in den Zustand, der dem Verzögerungsausgang entspricht, und verursacht einen verschachtelten Automaten. Beachten Sie, dass Aktionen unter den ZustĂ€nden eines Automaten (Aktionen von Moore-Automaten) erst initiiert werden, nachdem der Betrieb eines verschachtelten Automaten abgeschlossen ist. Sie setzen letztendlich den aktuellen Verzögerungswert und den Zustand der Ausgangsvariablen.

Wenn in Aktion y13 ein Verzögerungswert definiert ist, wird abhĂ€ngig von der Art der Verzögerung der erforderliche verschachtelte Automat erstellt. Der eingebettete Transportverzögerungsautomat zĂ€hlt einfach den eingestellten Wert der diskreten Zeittaktzyklen (die Dauer der Verzögerung wird durch die Anzahl der diskreten Taktzyklen bestimmt), und die TrĂ€gheitsverzögerung steuert zusĂ€tzlich den Eingangssignalpegel. In diesem Fall stellen wir fest, dass der zurĂŒckgegebene Wert des PrĂ€dikats x3 vom aktuellen Status des Automaten der obersten Ebene abhĂ€ngt.

Die Implementierung von Automaten in Abb. 8, 9 spiegelt Listing 3 wider. In Anbetracht des Codes sollten Sie auf die virtuelle Methode f () achten, die einerseits die eine oder andere ĂŒberlappende abstrakte logische Funktion implementiert und andererseits, falls angegeben, eine Inversion durchfĂŒhrt. All dies ist fĂŒr die Implementierung abgeleiteter Modelle logischer Elemente erforderlich. Listing 2 zeigt die Implementierung eines solchen NAND-Gatters.

Listing 1. Implementierung eines universellen Verzögerungslogikelements
#include "lfsaappl.h"

extern LArc TBL_DiscreteTime[];
class FDiscreteTime :											
	public LFsaAppl											
{													
public:													
    enum {cvarINE, cvarExlusiveOR, cvarOrNot};
    void MooreAction();
	bool	FCreationOfLinksForVariables();								
    LFsaAppl* Create(CVarFSA *pCVF) { Q_UNUSED(pCVF) return new FDiscreteTime(nameFsa); }
	bool FInit();											
    FDiscreteTime(string strNam, LArc* pTBL = TBL_DiscreteTime);
	~FDiscreteTime(void);										
	CVar *pVarType;		// delay type 0-transport; 1- inertial
	CVar *pVarX1;		// input variable
	CVar *pVarStrNameX1;	// input variable name
    	CVar *pVarIfNotX1;	// inverse of the first input variable
    	CVar *pVarY1;		// output variable
	CVar *pVarStrNameY1;	// output variable name
	CVar *pVarValue01;	// delay value from 0 to 1
	CVar *pVarValue10;	// delay value from 1 to 0
    	CVar *pVarNegationY;// output inversion 0 - no inversion; 1- inversion
    	virtual int x3();	// input analysis
	virtual int x12();	// link setup analysis
    	virtual bool f();
    	int nTypeElement;
protected:
// predicates												
    int x1();
// actions												
	void y1(); void y4(); void y5(); void y6(); void y7(); void y12(); void y13(); 
    bool bType{false};	// delay type: false - transport; true - inertial;
    bool bX1{false};
    int nCurrent{0};
    int nDelay{0};		// tech. delay counter value
    LFsaAppl	*pFCall{nullptr};
    friend class FCallTransport;
    friend class FCallInertial;
};		

class FCallTransport :
	public LFsaAppl
{
public:
	void MooreAction();
	FCallTransport(FDiscreteTime	*pFDiscreteTime);
	FDiscreteTime	*pFDiscreteTime;
protected:
	int x1();
};

class FCallInertial :
	public LFsaAppl
{
public:
	void MooreAction();
	FCallInertial(FDiscreteTime	*pFDiscreteTime);
	FDiscreteTime	*pFDiscreteTime;
protected:
    int x1(); int x3();
};

#include "stdafx.h"
#include "FDiscreteTime.h"											
#include "VARFSA/SetVarFsaLibrary.h"
//=====================================================================
//		Delay model at the upper structural level of the view
//=====================================================================
LArc TBL_DiscreteTime[] = {
    LArc("st",	"st","^x12","y12"),	//
    LArc("st",	"ss","x12", "--"),	//
    LArc("ss",	"s1","x3",  "y7y6y13"),// transition to a single state
    LArc("ss",	"s0","^x3", "y4y5y13"),// transition to zero state
// creation of a nested automaton at the transition to a single state
    LArc("s0",	"s1","x3",  "y13"),    
// creation of a nested automaton at the transition to the zero state
    LArc("s1",	"s0","^x3", "y13"),    
    LArc()
};
FDiscreteTime::FDiscreteTime(string strNam, LArc* pTBL):
    LFsaAppl(pTBL, strNam, nullptr, nullptr)
{ }
													
FDiscreteTime::~FDiscreteTime(void) { if (pFCall) delete pFCall; }

bool FDiscreteTime::FInit() {										
    FCreationOfLinksForVariables();
    return true;
}

bool FDiscreteTime::FCreationOfLinksForVariables()
{
// Local variables
    pVarNegationY = CreateLocVar("negation", CLocVar::vtBool, "output inversion: 0-without inversion / 1-inversion");
    pVarType = CreateLocVar("type", CLocVar::vtBool, "delay type: 0-transp / 1-inertia");
    pVarY1 = CreateLocVar("y", CLocVar::vtBool, "local output");
    pVarX1 = CreateLocVar("x1", CLocVar::vtBool, "local input");
    pVarValue01 = CreateLocVar("value to 1", CLocVar::vtInteger, "delay value from 0 to 1");
    pVarValue10 = CreateLocVar("value to 0", CLocVar::vtInteger, "delay value from 1 to 0");
    pVarStrNameX1 = CreateLocVar("strNameX1", CLocVar::vtString, "name of external input variable (x)");
    pVarStrNameY1 = CreateLocVar("strNameY", CLocVar::vtString, "name of external output variable (y)");
    pVarIfNotX1 = CreateLocVar("not(x1)", CLocVar::vtBool, "1st input inversion: 0-without inversion / 1-inversion");
    string str;
    str = pVarStrNameX1->strGetDataSrc();
    if (str != "") { pVarX1 = pTAppCore->GetAddressVar(pVarStrNameX1->strGetDataSrc().c_str(), this);	}
    str = pVarStrNameY1->strGetDataSrc();
    if (str != "") { pVarY1 = pTAppCore->GetAddressVar(pVarStrNameY1->strGetDataSrc().c_str(), this);	}
    return true;
}
// predicates
int FDiscreteTime::x1() { return nCurrent == nDelay; }
//  
int FDiscreteTime::x3() {
    if (bool(pVarNegationY->GetDataSrc())) return !f();
    return f();
}
//
int FDiscreteTime::x12() { return pVarX1 != nullptr; }
//
bool FDiscreteTime::f() {
    bX1 = bool(pVarX1->GetDataSrc());
    if (bool(pVarIfNotX1->GetDataSrc())) bX1 = !bX1;
    return bX1;
}
// actions
// +1 to the current delay value
void FDiscreteTime::y1() { nCurrent++; }
// setting the delay value when switching from 0 to 1
void FDiscreteTime::y4() { nDelay = int(pVarValue01->GetDataSrc()); }
// setting output to zero
void FDiscreteTime::y5() { pVarY1->SetDataSrc(nullptr, 0.0); }
// setting output to unit
void FDiscreteTime::y6() { pVarY1->SetDataSrc(nullptr, 1); }
// setting the delay value when switching from 1 to 0
void FDiscreteTime::y7() { nDelay = int(pVarValue10->GetDataSrc()); }
//
void FDiscreteTime::y12() { FInit(); }
// creation, if a delay is determined, of the necessary nested automaton
void FDiscreteTime::y13() {
	nCurrent = 0;
	if (pFCall) { delete pFCall; pFCall = nullptr; }
	if (x1()) return;
	bType = pVarType->GetDataSrc();		// set delay type
	if (bType) pFCall = new FCallInertial(this);
	else pFCall = new FCallTransport(this);
	if (pFCall) pFCall->FCall(this);
}

void FDiscreteTime::MooreAction()
{
	string strState = FGetState();
	if (strState=="s0")	{ 
        y4(); y5();		// y4) setting the delay value when switching from 0 to 1; y5) set the output to zero
    }
	else if (strState=="s1") { 
        y7(); y6();		// y7) setting the delay value when switching from 1 to 0; y6) setting the output to one
    }
}
//=====================================================================
//				Transport delay
//=====================================================================
static LArc TBL_CallTransport[] = {
	LArc("s5","s5","^x1",	"--"),		//
	LArc("s5","00","x1",	"--"),		// 
	LArc()
};

FCallTransport::FCallTransport(FDiscreteTime	*pFI):
    LFsaAppl(TBL_CallTransport, "FCallTransport", nullptr, nullptr)
{
	pFDiscreteTime = pFI;
}
// . == 
int FCallTransport::x1() { return pFDiscreteTime->x1(); }
//
void FCallTransport::MooreAction()
{
	string strState = FGetState();
	if (strState=="s5")	{ pFDiscreteTime->y1(); }
}
//=====================================================================
//				Inertial delay
//=====================================================================
static LArc TBL_CallInertial[] = {
	LArc("s5",	"s5","^x1x3",	"--"),		//
	LArc("s5",	"00","x1x3",	"--"),		//
	LArc("s5",	"XX","^x3",	"--"),		//
	LArc()
};

FCallInertial::FCallInertial(FDiscreteTime	*pFI):
    LFsaAppl(TBL_CallInertial, "FCallInertial", nullptr, nullptr)
{
	pFDiscreteTime = pFI;
}
// . == 
int FCallInertial::x1() { return pFDiscreteTime->x1(); }
// input value (depends on the name of the current state of the main automaton)
int FCallInertial::x3() {
	string strState = FGetStateUp();
	bool bX = pFDiscreteTime->x3();
    if (strState == "s0") return bX;
    if (strState == "s1") return !bX;
	if (strState == "st") {
		string str = pFDiscreteTime->FGetNextState();
		bX = pFDiscreteTime->x3();
		if (!bX) {
			if (x1()) {
                if (str == "s0") return !bX;
                if (str == "s1") return bX;
			}
            else return true;
		}
		return true;
	}
	else return bX; 
}
//
void FCallInertial::MooreAction()
{
	string strState = FGetState();
	if (strState=="s5")	{ pFDiscreteTime->y1(); }
}


Listing 2. Implementierung eines NAND-Gatters
#include "lfsaappl.h"

#include "../FDiscreteTime.h"
extern LArc TBL_DiscreteTime[];
class FIne :
	public FDiscreteTime
{
public:
    bool	FCreationOfLinksForVariables() override;
    LFsaAppl* Create(CVarFSA *pCVF) override { Q_UNUSED(pCVF) return new FIne(nameFsa); }
    bool FInit() override;
    FIne(string strNam, LArc* TBL = TBL_DiscreteTime);
    ~FIne(void);
	CVar *pVarX2;		//  
	CVar *pVarStrNameX2;	//    
	CVar *pVarIfNotX2;	//    
	virtual bool f() override;
protected:
    	int x12() override;
    	bool bX2;
};

#include "stdafx.h"
#include <Ine/FIne.h>
#include "VARFSA/SetVarFsaLibrary.h"

FIne::FIne(string strNam, LArc* pTBL):
    FDiscreteTime(strNam, pTBL)
{
    nTypeElement = FDiscreteTime::cvarINE;
}

FIne::~FIne(void) { }

bool FIne::FInit() {										
// 	 		
	FCreationOfLinksForVariables();
//	 										
	return true;										
}

bool FIne::FCreationOfLinksForVariables() {
//  
	FDiscreteTime::FCreationOfLinksForVariables();
	//      x1, x2
    pVarIfNotX2 = CreateLocVar("not(x2)", CLocVar::vtBool, " 2- : 0- /1-");
	pVarX2 = CreateLocVar("x2", CLocVar::vtBool, " 2- ");
    //  ,         x2
	pVarStrNameX2 = CreateLocVar("strNameX2", CLocVar::vtString, "  2- .(x)");
	// :   ,     
    string str = pVarStrNameX2->strGetDataSrc();
    if (str != "") { pVarX2 = pTAppCore->GetAddressVar(pVarStrNameX2->strGetDataSrc().c_str(), this); }
//
	return true;
}
//
int FIne::x12() { return FDiscreteTime::x12() && pVarX2 != nullptr; }
//
bool FIne::f() {
    //  1- 
    FDiscreteTime::f();
    //   
    bX2 = bool(pVarX2->GetDataSrc());
    if (bool(pVarIfNotX2->GetDataSrc())) bX2 = !bX2;
    //   : 
    return bX1&&bX2;
}


Dank OOP ist der Code des Modells des logischen Elements AND NICHT merklich kleiner als der Code der "ĂŒbergeordneten" Verzögerung. DarĂŒber hinaus wird es weitgehend durch die Notwendigkeit bestimmt, eine zusĂ€tzliche Eingabe fĂŒr das Modell des AND-Elements zu erstellen. Wenn die Modelle auf struktureller Ebene mit der Anzahl der Ein- / AusgĂ€nge ĂŒbereinstimmen, ist der Code noch kleiner. Der Implementierungscode fĂŒr das XOR-Gatter, der aus einem strukturell Ă€hnlichen Modell des AND-NOT-Elements generiert wurde, ist in Listing 3 dargestellt.

Listing 3. Exklusive OR-Gateway-Implementierung
#include <Ine/FIne.h>

extern LArc TBL_DiscreteTime[];
class FExlusiveOR :
    public FIne
{
public:
    LFsaAppl* Create(CVarFSA *pCVF) { return new FExlusiveOR(nameFsa); }
    FExlusiveOR(string strNam, LArc* TBL = TBL_DiscreteTime);
    ~FExlusiveOR(void);
protected:												
    bool f();
};

#include "stdafx.h"
#include "FExlusiveOR.h"

FExlusiveOR::FExlusiveOR(string strNam, LArc* pTBL):
    FIne(strNam, pTBL)
{
    nTypeElement = FDiscreteTime::cvarExlusiveOR;
}

FExlusiveOR::~FExlusiveOR(void) { }
//
bool FExlusiveOR::f() {
    FIne::f();
    return (bX1&&bX2)||(!bX1&&!bX2);
}


Hier ruft die f () -Methode der FExlusiveOR-Klasse die f () -Methode der FIne-Klasse nur auf, um die Werte der Eingabevariablen zu lesen, und ĂŒberlappt dann den Wert der NAND-Funktion mit dem Wert, der gemĂ€ĂŸ der logischen Funktion der neuen Klasse berechnet wurde. Im Bild und in der Abbildung können Modelle anderer logischer Elemente mit zwei EingĂ€ngen erstellt werden.

3. Schlussfolgerungen


Um eine digitale Schaltung zu implementieren, reicht der sogenannte funktional vollstĂ€ndige Satz von Logikelementen aus. Dies kann beispielsweise eine Menge von AND-, OR-, NOT-Elementen sein. Wir haben die Implementierung der folgenden logischen Elemente untersucht - Verzögerungen, die ein Wechselrichter sein können, AND-NOT- und EXCLUSIVE OR-Elemente. Sie beziehen sich auf die Grundelemente, die Teil eines funktional vollstĂ€ndigen Satzes sind. Um ein beliebiges Schema zu implementieren und / oder zu simulieren, muss der Bibliothek beispielsweise ein OR-NOT-Element hinzugefĂŒgt oder ein universelles benutzerdefiniertes Element implementiert werden, das fĂŒr ein Element aus einem funktional vollstĂ€ndigen Satz konfiguriert ist. Und das wird schon genug sein.

Auf der Grundlage der oben genannten Modelle verfĂŒgen wir daher angesichts der KPdSU-Umgebung ĂŒber eine vollwertige Umgebung fĂŒr die logische Modellierung digitaler Schaltkreise, mit der Sie aus jedem Bibliothekselement eine beliebige Anzahl von Prozessen generieren, konfigurieren und Verbindungen zwischen ihnen herstellen können. Gleichzeitig wird die Simulation detaillierter (unter BerĂŒcksichtigung aller Arten von Verzögerungen) und flexibler (Sie können die Elemente einzeln konfigurieren) als bei den beiden oben genannten typischen logischen Modellierungsmethoden - Kompilierung und Ereignis. Und es wird keine spezialisierte Umgebung sein, wie Das Modell der Softwareprozesse bleibt unverĂ€ndert und bleibt so universell wie jede andere objektorientierte Programmierumgebung, die auf der Verwendung der C ++ - Sprache basiert.

Und mehr ĂŒber ... wund. Es war einmal eine Zeit, in der man sich mit dem konfrontiert sah, was in der wissenschaftlichen Literatur falsch ist, oder genauer gesagt, eine Beschreibung eines logischen SchlĂŒsselelements wie eines RS-Triggers ist tatsĂ€chlich Analphabet, ebenso wie die Tatsache, dass selbst coole Elektronikingenieure nicht wissen, wie es im Detail funktioniert Ich habe viel Zeit damit verbracht, dies herauszufinden. Und ich kann berichten, dass es im Moment des Triggerproblems zumindest fĂŒr mich keine leeren Stellen gibt (siehe Details [3]). Und deshalb bleibt nur zu wundern, dass sich im Großen und Ganzen nichts Ă€ndert. Da die tabellarische Beschreibung des Auslösers frĂŒher gegeben wurde, wird sie auch heute noch gegeben, da es die berĂŒchtigten verbotenen ZustĂ€nde gab, und sie blieben dieselben, als sie sich ĂŒber das unvorhersehbare Umschalten des Auslösers beim Verlassen des verbotenen Zustands beschwerten, so dass sie immer noch in derselben Unwissenheit sind. Und das trotzdass Beispiele fĂŒr eine ausreichend genaue Beschreibung seines Verhaltens bereits bekannt sind (siehe zum Beispiel [4]).

Wahrlich: "Deine Taten sind wunderbar, Herr!" Nein, wie es scheint, auf den Köpfen solcher "RS-Trigger-Deskriptoren" ... automatische Programmierung und die in Betracht gezogene Methode zur Modellierung von Logikschaltungen in der VKPa-Umgebung. Wenn Sie zum Thema des Artikels zurĂŒckkehren und beispielsweise das obige Modell des NAND-Elements verwenden, können Sie auf einfache Weise ein Triggermodell erstellen und dessen Funktionsweise detailliert simulieren. Einschließlich der BerĂŒcksichtigung der Eigenschaften realer Logikelemente, die nur eine Art TrĂ€gheitsverzögerung aufweisen. Wenn Sie einen formalen Beweis fĂŒr die Eigenschaften eines Triggers benötigen, finden Sie ihn in [5].

Literatur
1. ., ., . UML. . . : , 2007. – 493 .
2. ., ., . : . . – .: , 1988. – 309 .
3. . [ ], : habr.com/ru/post/484588 . . . ( 07.01.2020).
4. . . 2- . – .: , 2004. – 432.
5. .. . [ ], : cloud.mail.ru/public/HwsK/T95PMM8Ed . . . ( 01.02.2020).

All Articles