تطبيق خوارزميات القصور الذاتي على مثال النمذجة المنطقية للدوائر الرقمية

1 المقدمة


ننتقل إلى الجزء الثاني من الموضوع المخصص للأتمتة المتداخلة. في البداية ، قمنا بفحص الخوارزميات العودية ، والتي ، مع وجود نموذج من الأتمتة المتداخلة وربط قدرات OOP ، تبين أنه ليس من الصعب تنفيذها. لكن إمكانيات التشغيل الآلي المتداخل لا تقتصر على ذلك. لذلك ، عند وصف نموذج التحكم في برامج التشغيل الآلي ، تم تحديد خوارزميات القصور الذاتي ، والتي تستند أيضًا إلى فكرة تضمين الأتمتة. من الصعب تصور خوارزميات القصور الذاتي في إطار مخطط الكتلة المعتاد للنموذج الحسابي ، والذي لا يوفر عودة التحكم إلى النقطة التي تسبق استدعاء الروتين الفرعي. ولكن يجب أن أقول أن الأتمتة التقليدية تنص أيضًا على إلغاء التحولات "بسرعة". ومع ذلك ، بالنسبة للأتمتة ، لا يمكن تخيل ذلك فحسب ، بل يمكن تنفيذه أيضًا.

الخوارزميات بالقصور الذاتي والنمذجة المنطقية للموضوعات ذات الصلة بالدوائر الرقمية. وليس ذلك كثيرًا لأن التأخير بالقصور الذاتي أعطى الاسم لفئة الخوارزميات قيد النظر ، ولكن كم كان معنى الإجراءات المتأخرة للتأخر بالقصور الذاتي ، والذي تم نقله إلى معنى عملهم. على الرغم من أنه ليس الاسم. في UML ، يتم تنفيذ خوارزميات مماثلة باستخدام مفهوم حالة التاريخ. التشابه واضح ، على الرغم من أن نمذجة الدوائر الرقمية في UML ، كقاعدة عامة ، غير وارد. إنه فقط أن المواقف عند العودة إلى نقطة البداية ، إذا أجبر أحد الأشخاص على القيام بذلك ، تبدو أكثر طبيعية. تشمل الأمثلة رفض شراء التذاكر ، وإلغاء العمليات / المعاملات المصرفية ، وقطع الاتصال بالشبكة ، وما إلى ذلك. إلخ في النهاية ، كما هو مذكور في UML ،بدون استخدام الحالات التاريخية ، لن يكون تنفيذ مثل هذه الخوارزميات "جميلاً" [1].

موضوع النمذجة المنطقية للدوائر الرقمية واسع ومثير للاهتمام في حد ذاته. والقراءة الجديدة لا تؤذيها. كما سنرى ، يمكن أن توفر تقنية البرمجة التلقائية طريقة أفضل لوصف الدوائر الرقمية وتنفيذها ونمذجتها منطقيًا. سنتعرف على كل هذا على نفس النحو ، سعينا وراء الهدف الرئيسي - للنظر في فئة مثيرة للاهتمام ومفيدة ، وأخيرًا ، مجرد فئة جميلة من الخوارزميات الطبيعية للأتمتة ، ولكن من الصعب جدًا تنفيذها في النماذج الحسابية الأخرى.

2. النمذجة المنطقية للدوائر الرقمية


عادة ما تأخذ الأدبيات بعين الاعتبار طريقتين لنمذجة الدوائر الرقمية - التجميع والحدث. التجميع محدود في قدراته ، لأنه لا يأخذ في الاعتبار تأخيرات العناصر ، ويتطلب عناصر الترتيب وكسر الملاحظات [2]. لا تحتوي طريقة الحدث على مثل هذه القيود وتستند إلى أحداث التتبع المرتبطة بالتغيرات في قيم الإشارة داخل الدائرة. لن نأخذ في الاعتبار التجميع ، ولكننا سنركز على مقارنة الحدث بالطريقة المطبقة في إطار إمكانيات البرمجة التلقائية ، والتي سنستدعيها أيضًا ، وفقًا لذلك ، بطريقة تلقائية.

كمثال ، خذ الدائرة من [2] ، كما هو موضح في الشكل. 1. يوضح الشكل التوضيحي لعملها من المصدر. 2. يتم النظر في خيارين: بتأخير واحد ، عندما يكون للعناصر المنطقية للدائرة نفس التأخير ، وبتأخير موزع ، عندما يكون للعناصر B و E تأخير مرتين مثل بقية عناصر الدائرة.
صورة

تين. 1. مثال على الدائرة.

صورة

تين. 2. أمثلة على النمذجة: أ - تأخير واحد ؛ ب - التأخير الموزع.

باستخدام طريقة المحاكاة التلقائية ، لن تضطر حتى إلى ابتكار شيء ما ، لأنه ليست هناك حاجة لإنشاء لغة محددة بما فيه الكفاية لوصف الدائرة والهياكل التي تنفذ علاقات الدائرة ، ولا تحتاج إلى خوارزميات محددة بما يكفي للكشف عن الأحداث في عملية نمذجة الدائرة ، والتي تعمل بعد ذلك كأساس لإنشاء مخططات تدفق للدائرة (للحصول على وصف لكليهما ، انظر [2] )

في حالة التشغيل الآلي ، يتم إنشاء نماذج العناصر المنطقية المعتادة لتقنية التشغيل الآلي لتصميم البرنامج ، والتي يتم تضمينها في مكتبة العناصر المنطقية (BLE). علاوة على ذلك ، على أساس هذه المكتبة ، يتم إنشاء مجموعة من عمليات الأوتوماتون المتوازية المقابلة لعدد عناصر الدائرة ، والتي يشار إليها فيما بينها باستخدام قنوات الإدخال / الإخراج لنماذج العناصر المنطقية (لهذا ، في بيئة VKPA ، غالبًا ما تكون متغيرات العملية المحلية كافية تمامًا). في الختام ، يتم استكمال نموذج الدائرة بمولدات العمليات لإشارات الإدخال وعمليات عرض الرسوم البيانية للإشارة.

نتائج المحاكاة للمثال المدروس في بيئة VKPa ، موضحة في الشكل. 3 تتزامن تمامًا مع المخططات في الشكل. 2. صحيح أنه لم يكن من الممكن على الفور تحقيق مثل هذه المصادفة. وليس بسبب مشاكل في النماذج ، ولكن لأنه في الواقع كان على "طريقة الاختيار العلمي" أن تحسب مدة إشارات الإدخال ، والتي ، كما اتضح ، لها تأثير كبير. ولكن في [2] لم يتم قول كلمة عن هذا ولا عن معلمات إشارات الإدخال. تم التوصل إلى اتفاق كامل من خلال اكتشاف أن 1) مدة تساوي ثلاث مرات التأخير ضروري ، و 2) يجب أن تتحول الإشارة (ب) فيما يتعلق بالإشارة (أ) لفترة تساوي تأخرًا واحدًا. لشرح هذه المشكلة ، انظر الشكل. يوضح الشكل 4 مخططات الإشارات لفترات مختلفة لإشارات الإدخال (وهذا دون مراعاة إزاحتها).

صورة

تين. 3. نتائج المحاكاة في VKPa: أ - تأخير واحد ؛ ب - التأخير الموزع.

صورة

تين. 4. نتائج المحاكاة مع فترات مختلفة لإشارة الإدخال

النظر في مثال آخر لدائرة من نفس المصدر [2]. يظهر مخططها ومخططات توقيت عملها في الشكل. 5. في إطار طريقة الحدث ، "لحساب" الرسم البياني الزمني ، كانت هناك حاجة إلى 20 خطوة محاكاة (لمزيد من التفاصيل انظر [2]). ولكن ، كما هو مذكور هناك ، هناك حاجة إلى خوارزمية أكثر تعقيدًا ، وبالتالي ، عدد أكبر من الخطوات إذا تم اختيار نوع التأخير القصوري. في حالتنا (حالة طريقة النمذجة التلقائية) ، مع وجود النموذج السابق ، نحتاج إلى "20 نقرة" بالماوس للانتقال إلى الرسم التخطيطي في الشكل. 5 ، إزالة العناصر غير الضرورية من الدائرة الأصلية. تظهر نتائج محاكاة الدائرة التي تم الحصول عليها في VKPa في الشكل. 6.

صورة

تين. 5. مثال على الدائرة ومخططها الزمني.

بالإضافة إلى ذلك ، الرسم التخطيطي في الشكل. 5 أضفنا بالتوازي مع العنصر أو العنصر الأول. الرسم البياني د في الشكل. يعرض 6 تشغيله لحالة تأخير واحد. إذا قمنا بتعيين تأخير كبير وقمنا بتعيين نوع التأخير القصوري ، فإن الرسم البياني d سيتحول إلى خط مستقيم. لذلك ، فإن العنصر And ذو تأخر القصور الذاتي أكبر من قيمة واحدة لن يغيب عن النبض المتولد عند مدخلاته عن طريق مجموعة من إشارات الإدخال هذه a و b. لاحظ أن معالجة نوع التأخير لا معنى له إلا للعناصر التي لها تأخير أكبر من واحد.

صورة

تين. 6. نمذجة الدائرة في الشكل. 5 وعنصر و (د).

3. تنفيذ العناصر المنطقية


في الحالة العامة ، يمكن تمثيل أي عنصر منطقي كوصلة متسلسلة من كتلتين (انظر الشكل 7) - عنصر منطقي مثالي بدون تأخير وكتلة ، والتي يمكن اعتبارها تأخير انتشار (تأخير النقل) أو تأخر قصوري [2].

صورة

تين. 7. نموذج عنصر المنطق المتأخر.

يتم تنفيذ العنصر المنطقي المثالي بسهولة بالغة بواسطة وظيفة منطقية عادية ، ويمكن تمثيل نموذج كتلة التأخير في شكل نموذج آلي - نموذج عالمي يتضمن النقل وتأخير القصور الذاتي. يظهر نموذج لمثل هذا التأخير الشامل في الشكل. يظهر الشكل 8 ، ونماذج الأتمتة المتداخلة لذلك في الشكل. 9. يظهر تنفيذها في C ++ وكجزء من تقنية البرمجة الآلية في القائمة 1.

صورة

تين. 8. نموذج التأخير الشامل.

صورة

تين. 9. نماذج الأتمتة المتداخلة للتأخير العالمي.

الآلات في الشكل. 8 والتين. 9 بنادق هجومية مختلطة من ميلي مور. تشغيل المحرك الرئيسي في الشكل. 8. يبدأ بإنشاء المتغيرات المحلية وتهيئة المراجع في الإجراء y12 (يتحقق x12 المسند كل هذا). الحالة المتوسطة "ss" ضرورية لكي يعمل x3 الأصلي بشكل صحيح ، والذي له ارتباط بمتغير إدخال ، والذي قد لا تتم تهيئته. من حالة "ss" ، ينتقل النموذج إلى الحالة المقابلة لمخرجات التأخير ، بينما يتسبب في تشغيل آلي متداخل. لاحظ أنه سيتم بدء الإجراءات بموجب حالات الأوتوماتي (إجراءات Moore automata) فقط بعد اكتمال تشغيل الأوتوماتيكية المتداخلة. سيقومون في النهاية بتعيين قيمة التأخير الحالية وحالة متغير الإخراج.

الإجراء y13 ، إذا تم تحديد قيمة التأخير ، يقوم بإنشاء المحرك المتداخل الضروري بناءً على نوع التأخير. يقوم جهاز تأخير النقل المضمّن تلقائيًا بحساب القيمة المحددة لدورات ساعة الوقت المنفصلة (يتم تحديد مدة التأخير من خلال عدد دورات الساعة المنفصلة) ، كما يتحكم التأخير بالقصور الذاتي في مستوى إشارة الإدخال. في هذه الحالة ، نلاحظ أن القيمة المرتجعة للمسند x3 تعتمد على الحالة الحالية لأوتوماتي المستوى الأعلى.

تنفيذ الأتمتة في الشكل. 8 ، 9 تعكس القائمة 3. بالنظر إلى الشفرة ، يجب الانتباه إلى الطريقة الافتراضية f () ، التي تنفذ ، من ناحية ، وظيفة منطقية مجردة متداخلة متداخلة ، ومن ناحية أخرى ، تقوم بإجراء انعكاس ، إذا كان محددًا. كل هذا ضروري لتنفيذ النماذج المشتقة من العناصر المنطقية. يوضح الإدراج 2 تنفيذ مثل هذه البوابة NAND.

القائمة 1. تنفيذ عنصر منطق تأخير عالمي
#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(); }
}


قائمة 2. تنفيذ بوابة NAND
#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;
}


بفضل OOP ، فإن رمز نموذج العنصر المنطقي AND ليس أصغر بشكل ملحوظ من رمز التأخير "الرئيسي". علاوة على ذلك ، يتم تحديده إلى حد كبير من خلال الحاجة إلى إنشاء مدخلات إضافية لنموذج العنصر AND. إذا ، على المستوى الهيكلي ، تطابق النماذج مع عدد المدخلات / المخرجات ، فسيكون الرمز أصغر. لذلك ، يظهر رمز التنفيذ لبوابة XOR التي تم إنشاؤها من نموذج مماثل من الناحية الهيكلية للعنصر AND-NOT في القائمة 3.

قائمة 3. التنفيذ الحصري أو بوابة
#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);
}


هنا ، تستدعي طريقة f () لفئة FExlusiveOR طريقة f () لفئة FIne فقط لقراءة قيم متغيرات الإدخال ، ثم تداخل قيمة دالة NAND مع القيمة المحسوبة وفقًا للوظيفة المنطقية للفئة الجديدة. في الصورة والتشابه ، يمكن إنشاء نماذج لأي عناصر منطقية ثنائية المدخلات.

3. الاستنتاجات


لتنفيذ أي دائرة رقمية ، يكفي ما يسمى مجموعة كاملة من العناصر المنطقية وظيفيا. يمكن أن يكون ، على سبيل المثال ، مجموعة من عناصر AND و OR و NOT. لقد درسنا تنفيذ العناصر المنطقية التالية - التأخيرات ، التي يمكن أن تكون عاكسًا ، و AND-NOT و EXCLUSIVE OR element. إنها تتعلق بالعناصر الأساسية التي تعد جزءًا من مجموعة كاملة وظيفياً. من أجل تنفيذ و / أو محاكاة أي مخطط ، يبقى الإضافة إلى المكتبة ، على سبيل المثال ، عنصر OR-NOT أو تنفيذ عنصر مخصص عالمي تم تكوينه على عنصر من مجموعة كاملة وظيفيا. وهذا سيكون كافيا بالفعل.

ونتيجة لذلك ، على أساس النماذج المذكورة أعلاه ، لدينا في مواجهة بيئة CPSU بيئة كاملة للنمذجة المنطقية للدوائر الرقمية ، والتي تتيح لك إنشاء أي عدد من العمليات من أي عنصر مكتبة ، وتكوينها وإقامة اتصالات بينها. في الوقت نفسه ، ستكون المحاكاة أكثر تفصيلاً (مع مراعاة جميع أنواع التأخيرات) ، وأكثر مرونة (يمكنك تكوين العناصر بشكل فردي) مما هي عليه في طريقتين النمذجة المنطقية النموذجية المذكورة أعلاه - التجميع والحدث. ولن تكون بيئة متخصصة ، كما لا يزال نموذج عمليات البرمجيات دون تغيير ؛ وسيبقى عالميًا مثل أي بيئة برمجة كائنية أخرى قائمة على استخدام لغة C ++.

وأكثر عن ... قرحة. ذات مرة ، واجهت ما هو خطأ في الأدبيات العلمية ، أو بشكل أدق ، وصف عنصر منطقي رئيسي مثل مشغل RS هو في الواقع أمي ، بالإضافة إلى حقيقة أنه حتى مهندسي الإلكترونيات الرائعين لا يعرفون كيف يعمل بالتفصيل الزناد ، قضيت الكثير من الوقت لمعرفة ذلك. ويمكنني أن أذكر أنه في الوقت الحالي في مشكلة الزناد ، على الأقل بالنسبة لي لا توجد نقاط فارغة (انظر التفاصيل [3]). وبالتالي يبقى فقط مندهشًا من أن لا شيء يتغير بشكل عام. كما تم تقديم الوصف المجدول للزناد في وقت سابق ، فإنه لا يزال يتم تقديمه اليوم ، حيث كانت هناك حالات ممنوعة سيئة السمعة ، وظلوا كما كانوا يشكون من التحول غير المتوقع للزناد عند الخروج من الحالة المحظورة ، لذلك لا يزالون في نفس الجهل. وهذا على الرغمأن الأمثلة على الوصف الدقيق بما فيه الكفاية لسلوكها معروفة بالفعل (انظر ، على سبيل المثال ، [4]).

حقاً ، "أعمالك رائعة يا رب!" لا ، على ما يبدو ، على رؤوس مثل "واصفات الزناد RS" ... البرمجة التلقائية والطريقة المدروسة لنمذجة الدوائر المنطقية في بيئة VKPa. وإذا عدت إلى موضوع المقالة ، فعلى سبيل المثال ، باستخدام النموذج أعلاه لعنصر NAND ، يمكنك بسهولة إنشاء نموذج تشغيل ومحاكاة تشغيله بالتفصيل. بما في ذلك مراعاة خصائص عناصر المنطق الحقيقي التي ليس لها سوى نوع من التأخيرات القصورية. حسنًا ، إذا كنت بحاجة إلى دليل رسمي على خصائص الزناد ، فسيتم تقديمه في [5].

المؤلفات
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