VHDL процес if-then-else-if оператор

Редактирах тази тема, за да актуализирам целия си нов проект и да го направя по-четлив:

--Propagate & generate team--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY PG_team_1bit IS
    PORT(a, b:IN STD_LOGIC;
         p: OUT STD_LOGIC;
         g: OUT STD_LOGIC);
END PG_team_1bit;
ARCHITECTURE PG_team_1bit_arch OF PG_team_1bit IS
BEGIN
    p <= a XOR b;
    g <= a AND b;      
END PG_team_1bit_arch;       


--Grey Box--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY Grey_box IS
    PORT(P, G, Gminus:IN STD_LOGIC;
         NewG: OUT STD_LOGIC);
END Grey_box;
ARCHITECTURE Grey_box_arch OF Grey_box IS
    SIGNAL temp: STD_LOGIC;
BEGIN
   temp <= P AND Gminus;
   NewG <= G OR temp;      
END Grey_box_arch;       


--Black Box--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY Black_box IS
    PORT(P, G, Pminus, Gminus:IN STD_LOGIC;
         NewP, NewG: OUT STD_LOGIC);
END Black_box;
ARCHITECTURE Black_box_arch OF Black_box IS
    SIGNAL temp: STD_LOGIC;
BEGIN
   NewP <= P AND Pminus;
   temp <= P AND Gminus;  
   NewG <= G or temp;    
END Black_box_arch;   


--Full adder--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY Full_Adder IS
    PORT(A, B, Cin:IN STD_LOGIC;
         S, Cout: OUT STD_LOGIC);
END Full_Adder;
ARCHITECTURE Full_Adder_arch OF Full_Adder IS
    SIGNAL p: STD_LOGIC;
BEGIN
   p <= A XOR B;
   S <= p XOR Cin;  
   Cout <= (A AND B) OR (A AND Cin) OR (B AND Cin);    
END Full_Adder_arch;  



--SKLANSKY SPARSE TREE ADDER 32 bit--
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
ENTITY SSTA32 IS
    PORT(A, B:IN STD_LOGIC_VECTOR(31 downto 0);
         S: OUT STD_LOGIC_VECTOR(32 downto 0));
END SSTA32;
ARCHITECTURE SSTA32_arch of SSTA32 IS 
    SIGNAL con: STD_LOGIC;
    SIGNAL p: STD_LOGIC_VECTOR(31 downto 0);
    SIGNAL g: STD_LOGIC_VECTOR(31 downto 0);
    SIGNAL NewGG: STD_LOGIC_VECTOR(6 downto 0);
    SIGNAL NewP: STD_LOGIC_VECTOR(6 downto 0);
    SIGNAL NewBG: STD_LOGIC_VECTOR(6 downto 0);
    variable j : integer := 0;
    variable k : integer := 0;
    variable l : integer := 0;
    variable m : integer := 0;
    variable d : integer := 0;
    variable e : integer := 0;
COMPONENT PG_team_1bit
    PORT(a, b:IN STD_LOGIC;
         p: OUT STD_LOGIC;
         g: OUT STD_LOGIC);
END COMPONENT; 
COMPONENT Grey_box IS
    PORT(P, G, Gminus:IN STD_LOGIC;
         NewG: OUT STD_LOGIC);
END COMPONENT;
COMPONENT Black_box IS
    PORT(P, G, Pminus, Gminus:IN STD_LOGIC;
         NewP, NewG: OUT STD_LOGIC);
END COMPONENT;
COMPONENT Full_Adder IS
    PORT(A, B, Cin:IN STD_LOGIC;
         S, Cout: OUT STD_LOGIC);
END COMPONENT;
BEGIN 
   con <= '1';
   GENERATE_LABEL_1:
   FOR i IN 0 TO 31 GENERATE
      PG_team_1bit_i: PG_team_1bit PORT MAP(a(i), b(i), p(i), g(i));
   END GENERATE GENERATE_LABEL_1;   
   GENERATE_LABEL_2: 
   FOR i IN 0 TO 31 GENERATE
       BEGIN
          F0 : IF ((i=1) OR (i=5) OR (i=9) OR (i=13) OR (i=17) OR (i=21) OR (i=25) OR (i=29)) GENERATE
             BEGIN Grey_box_i: Grey_box PORT MAP(p(i), g(i), g(i-1), NewGG(j));--
             j := j+1;
             END GENERATE F0;
          F1 : IF ((i/=1) AND (i/=5) AND (i/=9) AND (i/=13) AND (i/=17) AND (i/=21) AND (i/=25) AND (i/=29)) GENERATE
             BEGIN Black_box_i: Black_box PORT MAP(p(i), g(i), p(i-1), g(i-1), NewP(k), NewBG(k));
             k := k+1;
             END GENERATE F1; 
       END GENERATE GENERATE_LABEL_2;
   GENERATE_LABEL_3:
   FOR i IN 0 TO 31 GENERATE
      BEGIN
         F2 : IF (i=3) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(NewP(m), NewBG(m), NewGG(m), DNewG);
            m := m+1;
            END GENERATE F2;
         F3 : IF ((i=7) OR (i=11) OR (i=15) OR (i=19) OR (i=23) OR (i=27) OR (i=31)) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(NewP(m), NewBG(m), con, NewBG(m), TNewP(l), TNewBG(l));
            l := l+1; 
            END GENERATE F3;
      END GENERATE GENERATE_LABEL_3;
   GENERATE_LABEL_4:
   FOR i IN 0 TO 31 GENERATE 
      BEGIN
         F4 : IF (i=3) GENERATE
            BEGIN C(d) <= '0';
            d := d+1;
            C(d) <= NOT DNewG;
            d := d+1;
            END GENERATE F4;
         F5 : IF (i=7) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(TNewP(e), TNewBG(e), DNewG, DNewG2);
            C(d) <= NOT DNewG2;
            d := d+1;
            e := e+1;
            END GENERATE F5;
         F6 : IF (i=11) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(NOT TNewP(e), NOT TNewBG(e), DNewG2, C(d));
            d := d+1;
            e := e+1;
            END GENERATE F6;
         F7 : IF (i=15) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(TNewP(e), TNewBG(e), TNewP(e-1), TNewBG(e-1), QNewP, QNewBG);
            Grey_box_i: Grey_box PORT MAP(QNewP, QNewBG, DNewG2, DNewG3);
            C(d) <= DNewG3;
            d := d+1;
            e := e+1;
            END GENERATE F7;
         F8 : IF (i=19) GENERATE
            BEGIN Grey_box_i: Grey_box PORT MAP(NOT TNewP(e), NOT TNewBG(e), DNewG3, C(d));
            d := d+1;
            e := e+1;
            END GENERATE F8;
         F9 : IF (i=23) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(TNewP(e), TNewBG(e), TNewP(e-1), TNewBG(e-1), PNewP, PNewBG);
            Grey_box_i: Grey_box PORT MAP(PNewP, PNewBG, DNewG3, C(d));
            d <= d+1;
            e <= e+1;
            END GENERATE F9;
         F10 : IF (i=27) GENERATE
            BEGIN Black_box_i: Black_box PORT MAP(NOT TNewP(e), NOT TNewBG(e), PNewP, PNewBG, HNewP, HNewBG);
            Grey_box_i: Grey_box PORT MAP(HNewP, HNewBG, DNewG3, C(d));
            END GENERATE F10;
      END GENERATE GENERATE_LABEL_4;
   d := 0;
   GENERATE_LABEL_5:
   FOR i IN 0 TO 31 GENERATE
      BEGIN
         F11 : IF ((i=0) AND (d=0)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F11;
         F12 : IF ((i=4) AND (d=1)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F12;
         F13 : IF ((i=8) AND (d=2)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F13;
         F14 : IF ((i=12) AND (d=3)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F14;
         F15 : IF ((i=16) AND (d=4)) GENERATE
            BEGIN Cin <= C(d); 
            d := d+1;
            END GENERATE F15;
         F16 : IF ((i=20) AND (d=5)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F16;
         F17 : IF ((i=24) AND (d=6)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F17;
         F18 : IF ((i=28) AND (d=7)) GENERATE
            BEGIN Cin <= C(d);
            d := d+1;
            END GENERATE F18; 
         Full_Adder_i: Full_Adder PORT MAP(a(i), b(i), Cin, S(i), Cout);
         Cin <= Cout;
         F19 : IF (i=31) GENERATE
            BEGIN S(32) <= Cout;
            END GENERATE F19;
      END GENERATE GENERATE_LABEL_5;
END SSTA32_arch;

Грешките, които получавам, са следните: -Нестатични имена на сигнали за почти всички сигнали, които използвам. -Декларацията на променлива не е разрешена там, където го направих. -Неизвестни идентификатори. -Незаконна цел за присвояване на сигнал и -Незаконен паралелен оператор.

Някакви съвети как да ги поправя? Също така правилно ли е моето генериране, ако сега? Промених това, за да избегна процеси. Благодаря предварително


person Bobby Bob    schedule 05.10.2013    source източник


Отговори (2)


Отстъпете малко назад; ясно е, че все още не сте свикнали с VHDL; той е малко по-различен от другите езици и разликите честно (IMO) не са много добре преподавани в много (повечето?) книги.

Коригирането на синтактични грешки няма да ви помогне да преминете през това; научете се да виждате концептуалните грешки зад тях.

Някои текстове подчертават, че VHDL е език за описание на хардуер, а не език за програмиране: макар да е вярно, това не е особено полезно и може да ви доведе до лоши практики за проектиране на ниско ниво. Ето един различен поглед...

VHDL е на практика два различни езика в един: последователен език като Pascal или C и език за паралелна обработка като ... Не мога да се сетя за добър пример, но може би функционален език за програмиране като ML или Haskell (търпете ме на този бит...), където нещата се случват паралелно, а не в определен ред: истинската сила на VHDL е, че го прави безопасно!

В рамките на процес можете да го третирате като последователен език, с функции, процедури (невалидни функции за C програмисти!), променливи, цикли, if/then/else и позната последователна семантика - с ЕДНО изключение: Сигналите имат различна семантика, защото те са средството за комуникация между (обикновено различни) процеси. (Типичната C програма е единичен процес: ако пишете многонишкови C програми, ще знаете, че имате нужда от много различна дисциплина за тях и допълнителна поддръжка като библиотека с нишки).

Другият аспект на VHDL е паралелният аспект, където създавате множество единици - по същество всички процеси, работещи независимо един от друг, комуникиращи чрез сигнали. Извън процес имате различен набор от инструменти за програмиране:

  • Обектите/архитектурите са обвивки около група процеси.

  • Компонентите са едни и същи, защото те просто се нанасят върху обекти (чрез конфигурации, за да ви позволят да избирате различни обекти или архитектури). Ако не е необходимо да ги пренасочвате, можете да елиминирате компоненти и директно да инстанциирате обекти в дизайна.

  • Прости присвоявания на сигнали като p <= A XOR B; извън процес са съкращение за цялостен процес, който завършва това единично задание.

  • Има също условни назначения на сигнали и избрани назначения на сигнали, напр.

    p <= A when B = '1' else C; Това отново са стенограми за процеси.

  • Свързването на множество паралелни процеси става досадно: изразите Generate са инструменти за автоматизиране на тази работа.

Грешка е да се смесват двата домейна: като например използването на if/then/else или присвояване на променлива a := b; извън процес, или да се създаде екземпляр на компонент или да се използва Generate вътре в един. Сега, вътре в ARCHITECTURE SSTA32_arch of SSTA32 можете да видите такива грешки...

Няма да поправя проекта ви и не мисля, че искате да го правя; но ето няколко насоки:

  • Въпреки че можете да използвате променливи и присвояване на променливи извън процес, това обикновено е грешка: те са известни като „споделени променливи“ и (в термините на C програмиста) не е безопасен за нишкии обикновено няма да направи това, което очаквате. Използването на сигнали (и изучаването на тяхната семантика) е начинът да отидете тук.

  • Докато не можете да използвате if a then b else c; извън процес, МОЖЕТЕ да използвате if a generate b; end generate; if not a generate c; end generate; и можете да генерирате вложени изрази.

  • по-доброто форматиране ще улесни четенето и по-лесно забелязването на грешките.

  • Мисля, че може да искате "elsif" вместо "else if" на места: това адресира много липсващи проблеми с "end if"

РЕДАКТИРАНЕ: още насоки за актуализиран отговор...

  • „Декларацията на променливата не е разрешена“ в архитектурата все още е проблем ... на пръв поглед не можах да разбера защо не използвате сигнали.

  • На втори поглед:

     F2 : IF i=3 GENERATE
        BEGIN 
           Grey_box_i: Grey_box PORT MAP(NewP(m), NewBG(m), NewGG(m), DNewG);
           m := m+1;
        END GENERATE F2;
    

Не можете да използвате променливи в израз Generate като този (защото те са извън процес). Подозирам, че възнамерявате тяхната стойност да бъде по същество статична - детерминистична функция на (i), а не притежатели на състояние сами по себе си.

Компилаторът не знае това - той вижда повече състояние, което потенциално може да варира по време на изпълнение (и не можете да развивате повече хардуер по време на изпълнение!), така че отхвърля тази идея. Например няма подреждане на хардуера, генериран от Generate, като по този начин генерирането на последния случай "i=3" е напълно законно и нямате никакви гаранции за стойността на m. Резултатът вероятно няма да ви хареса!

Решението е просто: елиминирайте m като променлива и го направете функция на (i).

 function m(x : integer) return integer is
 begin
   case x is
      when 3      => return 0;
      when others => return 1;
   end case;
 end m;

 ... PORT MAP(NewP(m(i)), ...

Функциите принадлежат към архитектурата с другите декларации. Тъй като i е фиксиран (статичен) във всеки екземпляр на израз за генериране, f(i) - тук m(i) - също е статичен и въпреки че не съм тествал този подход, очаквам да работи.

  • Що се отнася до неизвестните идентификатори, виждам различни имена като DNEWG в горния фрагмент, за който не мога да намеря декларация; това е тривиално за решаване.

  • можете да загубите ненужните скоби около if-изразите; те са просто бъркотия, оставена от минаващ C програмист

person user_1818839    schedule 05.10.2013
comment
Здравейте благодаря за отговора. 1.по-доброто форматиране ще улесни четенето и ще улесни откриването на грешки. Искате да кажете след If и т.н., ако аз разделя? Очаквах да видя дали ще получа синтактична грешка, ако не използвам раздел, затова не го поправих. Някой го редактира вместо мен. Ще коригирам проекта си. 2. Относно elsif, да, ще коригирам и това. Пропуснах ги. 3. Ще се опитам да разбера какво казахте за крайното генериране на неща и ще се върна. Благодаря много за бързата помощ. - person Bobby Bob; 05.10.2013
comment
Ако можете да проверите отново частта за кодиране сега, когато се опитах да го поправя. Благодаря - person Bobby Bob; 06.10.2013
comment
1. Трябва ли да декларирам всеки сигнал, дори ако той излиза от PORT MAP на компонент като изход? 2. В решението, което добавихте, върнатите стойности ще отидат в променливата x, нали? И така, как това се свързва с i в PORT MAP? Също така не знам дали моето кодиране го направи ясно, но се опитвах да използвам всички променливи като индикатори и понякога дори да достигна стойност 31, индикаторът щеше да спре, да кажем на 7, защото само вътре в изразите if стойността ще се повиши. 3.Ще поправя скобите. Много, много благодаря за помощта досега. - person Bobby Bob; 06.10.2013
comment
1) Картата на портовете картографира компонентен порт към външен сигнал, така че да, трябва да има външен сигнал, към който да се картографира. (2) Не. Функцията извлича върнатата си стойност от формалния параметър x (към който предавате действителния параметър i). Върнатите стойности не отиват към никоя променлива; те се използват веднага (като индекс към масив NewP в примера. Да, разбирам, че индикаторът е функция на, а не негово копие; затова предлагам да го внедрите като ... функция. - person user_1818839; 06.10.2013

Отстъпът, базиран на структура, често разкрива проблеми със синтактиката, така че си позволих да разкрася вашия код. Както можете да видите в последната част, много от if изразите нямат правилни затварящи end if изрази. Тази синтактична грешка трябва да бъде коригирана и можете да обмислите използването на elsif за взаимно изключващите се условия.

Относно вашите въпроси:

  1. Какво трябва да поставя в списъка с чувствителност: За процес, който описва тригер(и), чувствителността трябва да отговаря на часовника и всеки асинхронен сигнал(и) за нулиране. За процес, който описва комбинаторна логика, списъкът на чувствителността трябва да съдържа всички сигнали на източника, които се използват в комбинаторната логика. Като цяло всеки процес, който пишете, трябва да бъде един от тези два, така че или да описва тригер(и), или да описва комбинаторна логика. Процесът след въпросите не е нито едно от двете и има множество проблеми: Не е позволено да се инстанцират модули, Grey_box и Black_box, вътре в процес и като цяло не можете да използвате k като променлива с := assign, без да го декларирате в процеса.

  2. Как мога да направя p и g глобални; дали това, което направих, не е достатъчно? p и g са налични, тъй като са декларирани в архитектурата, така че проблемът се дължи на опита за инстанциране на модул i процес, както отбелязах по-горе.

Като цяло може да обмислите да разберете по-добре концепцията на VHDL, преди да започнете по-голям проект като този, тъй като тогава ще бъде много по-лесно да разберете и коригирате всички съобщения за синтактични грешки, които срещате.

Добро място да започнете е VHDL страницата на Wikipedia, където можете да погледнете под Допълнителна литература. За да получите добро изживяване с VHDL, ви предлагам да се поразровите в някои от ресурсите, за да научите основните концепции.

person Morten Zilmer    schedule 05.10.2013
comment
Много благодаря за бързия отговор. Получих тези въпроси: 1. За процес, който описва комбинаторна логика, списъкът с чувствителност трябва да съдържа всички сигнали на източника, които се използват в комбинаторната логика. Тъй като моята логика е i(цяло число) в сравнение с нещо, как да направя това? Защото се опитах да сложа цяло число в скобите и се казва, че не мога да направя това. 2. опитът за инстанциране на модул i процес Прочетох това, докато търся. Можете ли да обясните тази причина, не разбирам какво означава. Благодаря предварително. - person Bobby Bob; 05.10.2013
comment
1: Проблемът не е свързан с типа (цяло число), но елементът в списъка за чувствителност трябва да е сигнал, следователно трябва да бъде деклариран в архитектурата. - person Morten Zilmer; 05.10.2013
comment
1: Проблемът не е свързан с типа (цяло число), но елементът в списъка за чувствителност трябва да е сигнал. 2: Страхотната публикация на Brian Drummonds описва два домейна и модулите са поставени в грешен домейн, тъй като не можете да поставите модули в процес. Предлагам ви да прекарате известно време в четене на общите принципи на VHDL и сами да напишете някои малки примери, тъй като той не е като другите езици за програмиране, където можете да използвате всички изрази във целия код. VHDL е език за описание на хардуера (HDL), където текстът описва хардуера, така че вашият код трябва да е хардуерен. - person Morten Zilmer; 05.10.2013
comment
Ако можете да проверите отново частта за кодиране сега, когато се опитах да го поправя. Благодаря - person Bobby Bob; 06.10.2013