عکس پیش‌فرض نوشته

یکی از مشکلاتی که اغلب طراحان در استفاده از دستورات انتساب سیگنال ترتیبی با آن مواجه می شوند این است که مقدار تخصیص یافته در آخرین انتساب بی درنگ ظاهر نمی شود. اگر طراح به مقدار جدید نیاز داشته باشد این مهم می تواند باعث رفتار نادرست مدل شود.

 
Learning VHDL
 

در اینجا مثالی از این مشکل ارائه شده است:

LIBRARY IEEE;
    USE IEEE.std_logic_1164ALL;
ENTITY mux IS
    PORT (I0, I2, I3, A, B :IN std_logic;
          Q : OUT std_logic);
END mux;

ARCHITECTURE mux_behave OF mux IS
    SIGNAL se1 : INTEGER RANGE 0 TO 3;
    BEGIN
    B : PROCESS(A, B, I0, I1, I2, I3);
        BEGIN
        Se1 <= 0;
        IF (A = ‘1’) THEN se1 <= se1 + 1; END IF;
        IF (B = ‘1’) THEN se1 <= se1 + 2; END IF;
        CASE se1 IS
            WHEN 0 =>
                Q <= I0;
            WHEN 1 =>
                Q <= I1;
            WHEN 2 =>
                Q <= I2;
            WHEN 3 =>
                Q <= I3;
        END CASE;
    END PROSECC;
END mau_behave;

 

این مدل یک مالتی پلکسر 4 به 1 است. بسته به مقادیر A و B ، یکی از چهار ورودی (I0 تا I3) به خروجی Q منتقل می شود.

معماری با دادن مقدار اولیه 0 به سیگنال داخلی se1 پردازش را شروع می کند. سپس برای انتخاب ورودی درست، بسته به مقادیر A و B مقدار 1 یا 2 به Se1 اضافه می شود. در پایان، براساس مقدار se1 یک دستور CASE انتخاب شده و مقدار ورودی را به خروجی Q منتقل می کند.

این معماری به صورتی که پیاده شده کار نمی کند. مقدار سیگنال se1 هرگز توسط نخستین خط معماری مقداردهی اولیه نمی شود:

Se1 <= 0;

این دستور درون یک PROCESS ، رویدادی با مقدار 0 را در دلتای زمانی بعدی برای سیگنال se1 زمان بندی می کند. به این ترتیب در دستور پروسس، پردازش با دستور ترتیبی بعدی ادامه می یابد. مقدار se1 هنگام ورود به پروسس در مقدار قبلی باقی می ماند. فقط هنگامی که پروسس تکمیل می شود، دلتای زمانی فعلی خاتمه می یابد و دلتای زمانی بعدی شروع می شود. پس از آن است که مقدار جدید se1 منعکس می شود.این درحالی است که کل پروسس با استفاده از مقدار اشباه se1 پیش رفته است.

دو روش برای برطرف کردن این مشکل وجود دارد.

نخستین روش درج دستور WAIT پس از هر دستور انتساب سیگنال ترتیبی است:

 

ARCHITECTURE mux_fix1 OF mux IS
    SIGNAL se1 : INTEGER RANGE 0 TO 3;
BEGIN
PROCESS
BEGIN
    Se1 <= 0;
    WAIT FOR 0 ns;

    IF (A = ‘1’) THEN se1 <= se1 + 1; END IF;
    WAIT FOR 0ns;

    IF (B = ‘1’) THEN se1 <= se1 + 2; END IF;
    WAIT FOR 0ns;

    CASE se1 IS
        WHEN 0 =>
            Q <= I0;
        WHEN 1 =>
            Q <= I1;
        WHEN 2 =>
            Q <= I2;
        WHEN 3 =>
            Q <= I3;
        END CASE;

    WAIT ON A, B, I0, I1, I2, I3;
    END PROSECC;
END mau_behave;

 

دستور WAIT پس از هر انتساب سیگنال باعث می شود پروسس قبل از ادامه اجرا، یک دلتای زمانی منتظر بماند. بواسطه این دلتای زمانی انتظار، مقدار جدید فرصت انتشار می یابد. بنابراین وقتی اجرا پس از دستور WAIT ادامه می یابد سیگنال se1 مقدار جدید را دارد.

اما، یکی از نتایج دستورات WAIT این است که پروسس دیگر نمی تواند لیست حساسیت داشته باشد. پروسسی که حاوی دستورات WAIT است و یا زیربرنامه ای را فرا می خواند که دستورات WAIT دارد نمی تواند لیست حساسیت داشته باشد. لیست حساسیت ایجاب می کند که اجرا از ابتدای روال شروع شود، اما دستور WAIT پروسس را در نقطه ای خاص به حالت تعلیق در می آورد. پس این دو با هم ناسازگارند.

چ.ن پروسس نمی تواند لیست حساسیت داشته باشد یک دستور WAIT به انتهای پروسس اضافه می شود که دقیقا رفتار لیست حساسیت را تقلید می کند.

دستور به صورت زیر است:

WAIT ON A, B, I0, I1, I2, I3;

 

هرگاه یکی از سیگنال های سمت راست کلید واژه ON رویدادی داشته باشد دستور WAIT پیش می رود. با این روش حل مشکل انتساب سیگنال ترتیبی، پروسس کار می کند اما راه حل بهتره استفاده از یک متغییر داخلی به جای سیگنال داخلیست:

ARCHITECTURE mux_fix2 OF mux IS
BEGIN
    PROCESS(A, B, I0, I1, I2, I3);
VARIABLE se1 : INTEGER RANGE 0 TO 3;
BEGIN
    Se1 := 0;
    IF (A = ‘1’) THEN se1 := se1 + 1; END IF;
    IF (B = ‘1’) THEN se1 := se1 + 2; END IF;

    CASE se1 IS
        WHEN 0 =>
            Q <= I0;
        WHEN 1 =>
            Q <= I1;
        WHEN 2 =>
            Q <= I2;
        WHEN 3 =>
            Q <= I3;
        END CASE;
    END PROSECC;
END mau_fix2;

 

سیگنال se1 مثال قبل از یک سیگنال داخلی به یک متغییر داخلی تبدیل شده است. این تبدیل با جا به جا کردن اعلان از بخش اعلان معماری به بخش اعلانی پروسس صورت پذیرفته است. متغییرها را فقط می توان در بخش اعلانی پروسس یا زیر برنامه ها اعلان کرد.

همچنین انتساب سیگنال به se1 با دستورات انتساب متغییر جایگزین شده اند. حال با اجرای نخستین تخصیص به se1 مقدار آن بی درنگ به روز می شود. هر تخصیص متوالی نیز بی درنگ اجرا می شود تا در هر دستور پروسس مقدار درست se1 در دسترس باشد.