Presentation is loading. Please wait.

Presentation is loading. Please wait.

Увод у VHDL.

Similar presentations


Presentation on theme: "Увод у VHDL."— Presentation transcript:

1 Увод у VHDL

2 Увод Строго типизиран. Није case sensitive. Основни елементи:
библиотека: LIBRARY naziv_biblioteke; USE naziv_biblioteke.naziv_paketa.deo_paketa; ентитет: ENTITY naziv_entiteta IS port( lista_portova); END [ENTITY][naziv_entiteta] архитектура: ARCHITECTURE naziv_arhitekture OF naziv_ent IS deklarativna_sekcija BEGIN konkurentni_iskazi END [ARCHITECTURE][naziv_arhitekture];

3 Лексички елементи Коментари Идентификатори Кључне речи
Специјални симболи Бројеви Карактери Стрингови Бит стрингови

4 Коментари Коментар до краја реда почиње са --
-- Ovo je komentar Стандард VHDL-2008 уводи и коментар у више редова /* Ovo je komentar u vise redova*/

5 Идентификатори Идентификатори: Проширени идентификатори
могу садржати мала и велика слова, бројеве и доњу црту "_"; морају почети словом, не смeју се завршити доњом цртом, не смeју садржати доњу црту два пута узастопно. Проширени идентификатори Од стандарда VHDL-93 Пишу се између карактера \ Могу да садрже све карактере

6 Примери Исправни: Неисправни: а а0 а_b а_b_c
\a____v$324\ -- проширени идентификатор Неисправни: a? недозвољен знак 0a не почиње словом ab_ завршава се са доњом цртом a__b --садржи двe узастопне доње црте

7 Кључне речи

8 Специјални симболи Један карактер
" # & ' ( ) * + - , . / : ; < = > [ ] ` | Више карактера => ** := /= >= <= <> ?? ?= ?/= ?> ?< ?>= ?<= << >> Значење: ** exponentiation, numeric ** integer, result numeric /= test for inequality, result is boolean

9 Целобројни литерали Декадне константе: 0 10 22
-32 је комбинација оператора '-' и константе 32 Декадне константе са експонентом: 10е2 12Е14 експонент је ненегативан цeо број Константе у основи из опсега 2..16: бинарна: 2# # = 2#1#е12 октална: 8#12000# = 8#12#Е3 хексадесимална: 16#F1A# =16#f1a#е0 Раздвајање цифара помоћу доње црте 2_150_252 2#1100_0101_1010#

10 Реални литерали Декадне реалне константе: 0.1 1.0 2.2
Декадне реалне константе константе са експонентом: 1.0е Е-14 експонент је цeо број Реалне константе у основи из опсега 2..16: бинарна: 2# # = 2#1.0#е12 октална: 8#1200.0# = 8#1.2#Е3 хексадецимална: 16#F1.A# = 16#f1.a#е0

11 Знаковни литерали и литерали стрингова
Знакови: 'а', 'А', '1', ... Стрингови: "Pera", "Mika", "Tekst ""pod"" dvostrukim navodnicima" Оператор & служи за надовезивање стрингова

12 Бит стрингови Стрингови који описују бинарне вредности
садрже само цифре у одговарајућој основи. Бројни системи: бинарни: B" ", B"0010_0110" октални: О"1532" хексадецимални: Х“a3b5" декадни: D"123" -- подржано тек у стандарду VHDL-2008

13 Типови VHDL је строго типизиран језик. Тип дефинише: Скаларни типови
скуп вредности могуће операције Скаларни типови цели бројеви реални бројеви физичке величине типови којима се описује један бит знакови набројиви логички Сложени типови фајлови низови записи

14 Целобројни типови Основни: INTEGER (по стандарду минимално 32 бита)
Дефинисање: RANGE izraz ( TO I DOWNTO ) izraz subtype small_int is integer range 0 to 10 ; to: растуће уређени бројеви downto: опадајуће уређени бројеви Операције: + сабирање – одузимање, или негација * множење / дељење mod модуо rem остатак abs апсолутна вредност ** експонент Различит тип од бит вектора Почетна вредност је најмања вредност у скупу

15 Дефинисање новог типа type_declaration ⇐ type identifikator_tipa is definicija_tipa ; Примери: type apples is range 0 to 100; type oranges is range 0 to 100; Типови су различити иако су дефиниције идентичне. Није дозвољено вредност једног типа доделити променљивој другог типа.

16 Дефинисање подтипа subtype_declaration ⇐ subtype identifikator is subtype_indication ; subtype_indication ⇐ type_mark [ range simple_expression ( to I downto ) simple_expression ] Пример: subtype small_int is integer range -128 to 127; variable pomeraj : small_int; variable pozicija : integer; Исправно је и: pozicija := pozicija + pomeraj; Резултат се може сместити и у објекат подтипа ако резултат изађе из опсега, пријављује се грешка.

17 Набројиви типови Дефинисање набројивог типа
type naziv_tipa is (prva_vrednost {,...} ); Пример: type stanje is (spreman, radi, zavrsio); Погодан за описивање машина стања Могуће мењати кодирање стања Напомена: константе истог назива из различитих типова су различите константе.

18 Физичке величине 1 hour = 3.6x1018 femtoseconds
Користи се за опис реалних физичких величина За нас од интереса само време: type time is range implementation defined units fs; ps = 1000 fs; ns = 1000 ps; us = 1000 ns; ms = 1000 us; sec = 1000 ms; min = 60 sec; hr = 60 min; end units; 1 hour = 3.6x1018 femtoseconds

19 Битови Предефинисани набројиви тип са могућим вредностима: '0' '1'
Дефинисане су стандардне логичке операције: and or not xor ...

20 std_logic Скуп могућих вредности: 'U' – неиницијализовано
'X' – строго непознато '0' – строго 0 '1' – строго 1 'Z' – стање високе импедансе 'W' – слабо непознато 'L' – слабо 0 'H' – слабо 1 '-' – није битно Ретко се користе све вредности Велики скуп различитих вредности боље моделује понашање реалног система олакшава детектовање и уклањање грешака За проверу поклапања нивоа испред релационих оператора додати упитник. Тачно је: '0' /= 'L' , али и '0' ?= 'L' На почетку сваког фајла неопходно укључити IEEE библиотеку: library ieee; use ieee.std_logic_1164.all;

21 Низови Дефинисање: TYPE naziv_tipa IS ARRAY(granica [TO|DOWNTO] granica {,...}) OF tip_pojedinačnog_elementa; Групишу више елемената истог типа заједно Погодни за опис магистрала: TYPE address_buss IS ARRAY (63 DOWNTO 0) OF std_logic; type matrix is array (integer range <>, integer range <>) of real; Постоје предефинисани типови: std_logic_vector bit_vector

22 std_logic_vector Не постоји нумеричка интерпретација std_logic_vector типа Аритметичке операције не постоје Сигнали std_logic_vector типа не могу да се користе као идекси низова Решење: Користити пакете из библиотека ieee.numeric_std и ieee.numeric_bit Користити пакете из библиотека ieee. std_logic_arith и ieee. std_logic_unsigned и ieee. std_logic_signed Препоручује се прва варијанта Не препотставља ништа о представи броја (све мора експлицитно) Друга је наметнута од стране једне компаније

23 numeric_std type UNSIGNED is array ( NATURAL range <> ) of STD_LOGIC; type SIGNED is array ( NATURAL range <> ) of STD_LOGIC; Id: A.3 function "+" (L,R: UNSIGNED ) return UNSIGNED; -- Result subtype: UNSIGNED(MAX(L'LENGTH, R'LENGTH)-1 downto 0). -- Result: Adds two UNSIGNED vectors that may be of different lengths.

24 numeric_std -- Id: D.1 function TO_INTEGER ( ARG: UNSIGNED) return NATURAL; -- Result subtype: NATURAL. Value cannot be negative since parameter is an -- UNSIGNED vector. -- Result: Converts the UNSIGNED vector to an INTEGER.

25 numeric_std signal reg : std_logic_vector(7 downto 0);
signal reg_unsigned:unsigned(7 downto 0); Конверзија UNSIGNED  STD_LOGIC_VECTOR reg_unsigned <= unsigned(reg); reg <= std_logic_vector(reg_unsigned);

26 numeric_std - конверзија

27 Типови

28 Подаци у VHDL Постоје 3 класе објеката за чување података: константе
променљиве сигнали

29 Константе Дефинисање: CONSTANT identifier { , … } : subtype_indication [ := expression ] ; За сада, израз за почетну вредност сматрамо обавезним. Примери дефинисања: constant number_of_bytes : integer := 4; constant number_of_bits : integer := 8 * number_of_bytes; constant e : real := ; constant prop_delay : time := 3 ns; constant size_limit, count_limit : integer := 255;

30 Променљиве Декларисање: VARIABLE identifier { , … } : subtype_indication [ := expression ] ; Користе се у процесима, потпрограмима и функцијама свака променљива сме бити видљива и коришћена у само једном процесу (осим дељених). Пример: variable index : integer := 0; variable sum, average, largest : real; variable start, finish : time := 0 ns; Последња линија је еквивалентна са: variable start : time := 0 ns; variable finish : time := 0 ns;

31 Додела вредности променљивој
promenljiva := izraz; Увек секвенцијални исказ Израз мора бити истог типа као и променљива Променљиве тренутно добијају нову вредност променљива може и у истом симулационом циклусу да промени вредност више пута, све промене су видљиве и у текућем симулационом циклусу.

32 Сигнали Концепт који је осмишљен да би се описале везе које постоје у реалним системима. Битно се разликују од променљивих. Дефинисање сигнала: SIGNAL identifikator {,...}: tip [register|bus] [:=izraz]; Израз за почетну вредност битан само при симулацији; при синтези се одбацује signal a_bit : bit := '0'; a_bit <= b_bit xor '1'; concurrent assignment

33 Додела вредности сигналу
Битно се разликује од доделе вредности променљивој: Додела вредности није тренутна – у току симулационог циклуса вредност сигнала се не мења. Дифинише се трансакција: вредност и тренутак када сигнал треба да добије задату вредност. Више сигнала може у истом тренутку променити вредност. Свака нова трансакција брише све трансакције заказане за исти или наредни тренутак за дати сигнал Врсте исказа за доделу вредности сигналу: секвенцијална, конкурентна.

34 Сигнали vs. Променљиве Сигнал Променљива Оператор доделе <= :=
Шта моделује Физичку везу Локалну информацију Опсег важења Може бити глобалан Локалан Понашање Додела није тренутна у секвенцијалном коду Додела је тренутна Употреба У пактерима, ентитетима и/или архитектурама У секвенцијалним изразима

35 Ентитет entity identifier is [ generic ( generic_list ) ; ] [ port ( port_interface_list ) ; ] { entity_declarative_item } end [ entity ] [ identifier ] ; interface_list ⇐ ( identifier { , … } : [ mode ] subtype_indication [ := expression ] ) { ; … } mode ⇐ in I out I buffer I inout Декларативни део ентитета је заједнички за све имплементације (архитектуре). buffer – као out који може и да се чита унутар архитектуре.

36 Архитектура architecture identifier of entity_name is { block_declarative_item } begin { concurrent_statement } end [ architecture ] [ identifier ] ; concurrent_statement <= concurrent_signal_assignment_statement | process_statement | block_statement | concurrent_procedure_call_statement | concurrent_assertion_statement | component_instantiation_statement | generate_statement

37 Конкурентна додела вредности сигналу
Постоје 3 врсте: Додела једног фиксног израза Додела једног од више израза: Селекциона додела вредности Условна додела вредности

38 Конкурентна додела фиксног израза
Додела вредности сигналу као исказ у телу архитектуре. Синтакса: [label:] (name|aggregate) <= [delay_mechanism] waveform delay_mechanism <= transport | [reject time_expression] inertial waveform <= (value_expression [after time_expression] | null [after time_expression]) {,...} | unaffected Извршава се увек када дође до догађаја на неком од сигнала који учествују у изразу за израчунавање нове вриједности. Генерише се комбинациона логика.

39 Пример entity mux is port(d0, d1, d2, d3, sel0, sel1:in bit; z:out bit); end entity; architecture dataflow of mux is begin zmux: z <= (d0 and not sel1 and not sel0) or (d1 and not sel1 and sel0) or (d2 and sel1 and not sel0) or (d3 and sel1 and sel0); end architecture;

40 Синтетизовани модел

41 Селекциона додела вредности
with expression select[?] name <= [delay_mechanism] {waveform when choices, } waveform when choices; Погодно када нова вредност зависи од вредности неког конкретног израза. Опциони упитник има исту улогу као испред релационих оператора. Пример alu: with alu_function select result <= a + b after Tpd when alu_add | alu_add_unsigned, a - b after Tpd when alu_sub | alu_sub_unsigned, a and b after Tpd when alu_and, a or b after Tpd when alu_or, a after Tpd when alu_pass_a;

42 Пример entity mux is port(d0, d1, d2, d3:in bit; sel:in bit_vector(1 downto 0); z:out bit); end entity; architecture dataflow of mux is begin with sel select z <= d0 when "00", d1 when "01", d2 when "10", d3 when "11"; end architecture;

43 Синтетизован модел

44 Условна додела вредности
name <= [delay_mechanism] {waveform when boolean_expression else } waveform [when boolean_expression]; Погодно када се услов не може за сваки случај добити поређењем вредности једног израза са неком вредношћу. Приоритетно испитивање услова; додељује се прва вредност код које је услов тачан и прекида се даље испитивање преосталих услова. Примјер zmux: z <= d0 when sel1 = '0' and sel0 = '0' else d1 when sel1 = '0' and sel0 = '1' else d2 when sel1 = '1' and sel0 = '0' else d3 when sel1 = '1' and sel0 = '1';

45 Синтетизован модел

46 Упоредни приказ претходна 3 синтетизована модела

47 Конкурентна додела вредности и секвенцијална логичка кола?
Претходни примери: Условна и селекциона додела вредности се синтетизују као комбинациона логичка кола У свим условима генерисана нова вриједност за сигнал Z. Уколико се догоди да при се промени неког улазног сигнала не дефинише нова вриједност сигнала Z, алати ће претпоставити да вриједност треба да остане неизмењена; Пошто се може догодити да то није била жеља дизајнера, алат ће дизајнера информисати о томе Вероватно ће бити генерисано упозорење да меморијски елементи можда неће радити како треба, зашто? Ако се секвенцијална логика формира на начин описан на датом слајду, у израчунавању нове вриједности ће учествовати сигнал који учествује и у израчунавању такта меморијског елемента те то може за резултат дати непредвидиву вредност. Пример дат на наредном слајду.

48 Пример – секвенцијално коло
entity mux is port(d0, d1, d3:in bit; sel0, sel1:in bit; z:out bit); end entity; architecture dataflow of mux is begin z <= d0 when sel1 = '0' and sel0 = '0' else d1 when sel1 = '0' and sel0 = '1' else --d2 when sel1 = '1' and sel0 = '0' else d3 when sel1 = '1' and sel0 = '1'; end architecture;

49 Синтетизовани модел – RTL поглед

50 Синтетизовани модел – технолошки поглед

51 Секвенцијално процесирање
Појављује се унутар процеса и потпрограма. Наредбе се извршавају у редоследу појављивања унутар процеса (потпрограма); редослед наредби из различитих процеса није дефинисан. Променљивим се вредност мења у тренутку извршавања исказа доделе вредности тој променљивој. Могу се користити и математички оператори. У току извршавања, време се не мења! За сваки процес мора се дефинисати под којим условима ће се активирати (шта је потребно да се догоди да се процес активира наредни пут).

52 Листа сигнала на које је процес осетљив – листа осетљивости процеса
Процес Листа сигнала на које је процес осетљив – листа осетљивости процеса Конкурентни исказ. Садржи секвенцијалне исказе. Синтакса: [labela_procesa:] process [(naziv_signala {,...})] is {deklarativna_sekcija} begin {sekvencijalni_iskaz} end process [labela_procesa]; Процес не мора да има листу сигнала на које је осетљив активира се на почетку симулације активира се сваки пут када се "пробуди" са неког wait исказа кад дође до краја, враћа се на почетак Уколико процес има и листу сигнала на које је осетљив: активира се и суспендује исто као да нема листу осетљивости суспендује се увек када дође до краја процеса Догађај на сигналу из листе осетљивости => процес се активира ако је суспендован због доласка до краја.

53 Секвенцијални искази sequential_statement <= wait_statement | report_statement | variable_assignment_statement | if_statement | loop_statement | exit_statement | null_statement | assertion_statement | signal_assignment_statement | procedure_call_statement | case_statement | next_statement | return_statement

54 Секвенцијална додела вредности сигналу
Додела вредности сигналу унутар процеса Сваки процес добија по један драјвер за сваки сигнал којем додељује вредност Уколико се у неком случају сигналу не додели вредност, памти се претходна (секвенцијална кола). У једном симулационом циклусу може се изгенерисати више трансакција за исти сигнал Конкурентна додела вредности сигналу еквивалентна је процесу: који садржи исту такву секвенцијалну доделу и који у листи сигнала на које је осетљив има све сигнала који се користе при израчунавању нове вредности сигнала Од ВХДЛ 2008 уведени су секвенцијални искази за селекциону и условну доделу вредности сигналу.

55 Пример entity mux is port(d0, d1, d2, d3, sel0, sel1:in bit; z:out bit); end entity; architecture dataflow of mux is begin process (d0, d1, d2, d3, sel0, sel1) is begin zmux: z <= (d0 and not sel1 and not sel0) or (d1 and not sel1 and sel0) or (d2 and sel1 and not sel0) or (d3 and sel1 and sel0); end process; end architecture;

56 Механизми кашњења Два могућа: delay_mechanism <= transport |
транспортни инертни (подразумевани) delay_mechanism <= transport | [reject time_expression] inertial Користе се само за потребе симулације: симулира се кашњење логичких кола симулира се кашњење веза између логичких кола При синтези ова кашњења се занемаре => на овај начин није могуће мерити време за потребе имплементације неког алгоритма

57 Транспортно кашњење Транспортни механизам кашњења (transport)
Мора се експлицитно навести Све трансакције се генеришу са наведеним кашњењем Опонаша кашњење које настаје дуж линија за пренос сигнала (идеалне линије која пропушта све фреквенције) Није погодно за опис логичких кола

58 Примери Пример који генерише две трансакције у току једног симулационог циклуса на једном сигналу: entity е1 is end e1; architecture а1 of е1 is signal a:bit:='1'; begin process a <= transport '0' after 1ns; a <= transport '1' after 2ns; wait; end process; end а1; Пример у којем остаје само једна трансакција (дат само измењени део) каснија трансакција је за ранији тренутак од претходне и због тога се претходно генерисана трансакција брише. 0ns 1ns 2ns 0ns 1ns 2ns

59 Транспортно кашњење - пример
transmission_line: process(a) is begin z <= transport a after 500 ps; end process transmission line; a z 700 ps 1 1000 ps

60 Транспортно кашњење - пример
transmission_line: process(a) is begin if a=‘1’ z <= transport a after 800 ps; else z <= transport a after 500 ps; end process transmission line; a z 1000 ps 1 900 ps postoji transakcija, ali ne i događaj

61 Инертно кашњење Подразумеван ако се не наведе ниједан
Инертни механизам кашњења (inertial) Подразумеван ако се не наведе ниједан Побудни сигнал мора да постоји дуже од времена одбацивања Економичан за ресурсе симулатора Гличеви се не пропагирају кроз дизајн Брише и све трансакције заказане у претходном интервалу одбацивања, почев од прве која се разликује од нове вредности гледано са краја интервала Упрошћено: одбацује све импулсе који нису дужи од времена одбацивања

62 Инертно кашњење - пример
inv: process(a) is begin z <= inertial not a after 3 ns; end process inv; a z

63 Инертно кашњење - пример
inv: process(a) is begin z <= reject 1 ns inertial not a after 3 ns; end process inv; a z reject 0 ps inertial a  transport a

64 Инертно кашњење - пример
inv: process(a,b) is begin z <= reject 3 ns inertial a or b after 5 ns; end process inv;

65 Пример entity primer is end primer;
architecture ponasanje of primer is signal a:bit:='1'; signal b:bit:='0'; begin process variable c:bit:='0'; begin if (a='1')or(b='0') then a <= inertial not c after 1ns; else a<=inertial not c after 1.5ns; end if; b <= inertial (b)nand(a or c) after 1ns; c := a and b; wait on a, b; end process; end ponasanje;

66 Агрегација сигнала aggregate ⇐ ( ( [ choices => ] expression ) { , … } ) choices ⇐ ( simple_expression I discrete_range I others ) { | … } Примјери: type byte is array (7 downto 0) of bit; signal d_reg : byte; signal a, b : bit; d_reg <= (a, "1001", b, "00"); d_reg <= (7 => a, 6 downto 3 => "1001", => b, 1 downto 0 => "00");

67 Агрегација сигнала signal status_reg : bit_vector(7 downto 0); signal int_priority, cpu_priority : bit_vector(2 downto 0); signal int_enable, cpu_mode : bit; (2 downto 0 => int_priority, 6 downto 4 => cpu_priority, 3 => int_en, 7 => cpu_mode) <= status_reg;

68 Комбинационе мреже – примери
Ефикасно HDL моделовање Дељење оператора Дељење функционалности Оптимизација распоређивања Опште мреже

69 Ефикасно HDL моделовање
Језик за МОДЕЛОВАЊЕ HARDWARE-a Погрешан приступ Замислити C програм и превести га у HDL Добар приступ Истраживање области да се пронађе ефикасан модел Преточити модел у HDL код

70 Дељење Сложеност физичких модела варира Аритметички оператори
Гломазни Оптимизација од стране алата минимална Оптимизација постигне дељењем на RT нивоу Оператори Функционалност

71 CMOS имплементација стандардних ћелија

72 Дељење оператора Израчунавање израза је међусобно искључено
Само један резултат се прослеђује на излаз Пример - условна додела вредности сигналу sig <= value_1 when boolean_1 else value_2 when boolean_2 else value_3 when boolean_3 else . . . value_n;

73 Дељење оператора – пример (1)
Код: r <= a+b when boolean_exp else a+c; Модификован код: src0 <= b when boolean_exp else c; r <= a + src0;

74 Дељење оператора – пример (2)
Простор: 2 add, 1 mux Кашњење: max(Tadd, Tbool) + Tmux Простор: 1 add, 1 mux Кашњење: Tadd + Tbool + Tmux

75 Дељење оператора Дељење се ради додавањем мреже за рутирање
Добробити од дељења зависи од сложености имплементације оператора и мреже за рутирање Идеално – алат обавља овај посао

76 Дељење функционалности
Велика мрежа може имати пуно функционалности Неколико функција могу бити сличне Неколико функција могу да деле исти hardware Ради се ad hoc Алат не може лако да одради дељење, јер не разуме функционалности

77 Компаратор – пример (1) Компаратор са два мода 8 бита
Неозначени бројеви Означени бројеви 8 бита Размислити о проширењу

78 Компаратор – пример (2) library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity cmp2m is port( a,b: in std_logic_vector(7 downto 0); mode : in std_logic; f_out : out std_logic ); end cmp2m;

79 Компаратор – пример (3) architecture direct_arch of cmp2m is signal f_out_signed, f_out_unsigned : std_logic; begin f_out_signed <= '1' when signed(a) > signed(b) else '0'; f_out_unsigned <= '1' when unsigned(a) > unsigned(b) else f_out <= f_out_unsigned when mode = '0' else f_out_signed; end direct_arch;

80 Компаратор – пример (4)

81 Компаратор – пример (5) architecture shared_arch of cmp2m is signal a1_b0, f_out_cmp : std_logic; begin a1_b0 <= '1' when a(7) = '1' and b(7) = '0' else '0'; f_out_cmp <= '1' when a(6 downto 0) > b(6 downto 0) else f_out <= f_out_cmp when (a(7) = b(7)) else a1_b0 when mode = '0' else not a1_b0; end shared_arch;

82 Компаратор – пример (6)

83 Оптимизација распоређивања
“Place and route” после синтезе VHDL не може да специфицира тачан распоред VHDL може да специфицира приближан облик Чип је дводимензионалан Дводомензионални облик бољи од једнодимензионог Условна додела генерише хоризонталан ланац Селекциона додела генерише вертикалан ланац Ни један ни други није идеалан

84 Вишебитно XOR коло (1)

85 Вишебитно XOR коло (2) Проблем? library ieee; use ieee.std_logic_1164.all; entity r_xor is port(a: in std_logic_vector(7 downto 0); f : out std_logic); end r_xor; architecture cascade_arch_1 of r_xor is begin f <= a(0) xor a(1) xor a(2) xor a(3) xor a(4) xor a(5) xor a(6) xor a(7); end cascade_arch_1;

86 loop iskaz Бесконачна петља; могуће искочити из средине.
[ loop_label : ] loop { sequential_statement } end loop [ loop_label ] ; Пример: incrementer : process is variable count_value : natural := 0; begin count <= count_value; loop wait until clk; count_value := (count_value + 1) mod 16; count <= count_value; end loop; end process incrementer;

87 exit Исказ којим се излази из петље.
exit [ loop_label ] [ when condition ] ; У зависности да ли је лабела наведена или не зависи која петља се заврши: наведена лабела => излази се из петље означене са том лабелом, без лабеле => излази се из окружујуће петље.

88 Пример outer : loop inner : loop exit outer when condition_1; -- target B exit when condition_2; -- target A end loop inner; target A exit outer when condition_3; -- target B ... end loop outer; target B

89 next Прескаче остатак текуће итерације петље.
[ label : ] next [ loop_label ] [ when condition ] ; Уколико се специфицира нека окружујућа петља, угнежђене петље се завршавају и прескаче се остатак текуће итерације наведене петље.

90 while loop Петља са условом на почетку.
[ loop_label : ] while condition loop { sequential_statement } end loop [ loop_label ] ;

91 for loop [ loop_label : ] for identifier in discrete_range loop { sequential_statement } end loop [ loop_label ] ; discrete_range => simple_expression ( to I downto ) simple_expression Бројачку променљиву (идентификатор непосредно после for): није потребно експлицитно дефинисати, може се користити само у телу петље, није дозвољен упис у бројачку променљиву, прикрива друге променљиве истог назива.

92 Пример лоше употребе erroneous : process is variable i, j : integer; begin i := loop_param; -- error! for loop_param in 1 to 10 loop loop_param := 5; -- error! end loop; j := loop_param; -- error! end process erroneous;

93 Вишебитно XOR коло (3) architecture cascade_arch_2 of r_xor is constant WIDTH:integer :=8; begin process (a) variable tmp : std_logic; tmp:= a(0); for i in 1 to WIDTH - 1 loop tmp:= tmp xor a(i); end loop; f <= tmp; end process; end cascade_arch_2;

94 Вишебитно XOR коло (4) architecture cascade_arch_3 of r_xor is constant WIDTH:integer :=8; signal p: std_logic_vector(WIDTH -1 downto 0); begin p <= (p(WIDTH - 2 downto 0) & '0') xor a; f <= p(WIDTH - 1); end cascade_arch_3;

95 Вишебитно XOR коло (5) architecture tree_arch of r_xor is begin f <= (((a(0) xor a(1)) xor (a(2) xor a(3))) xor ((a(4) xor a(5)) xor (a(6) xor a(7)))); end tree_arch;

96 Вишебитно XOR коло (6)

97 Вишебитно XOR коло (7) Упоређивање
Ланац Простор: (n – 1) xor кола Кашњење: (n – 1) Кодирање: Лако се скалира Дрво Кашњење: log2n Кодирање:не скалира се лако У зависности од алата и технологије имплементације конверзија може да буде аутоматска

98 Опште мреже Пример – Грејев бројач

99 Грејев бројач (1) library ieee; use ieee.std_logic_1164.all; entity gray_inc is port( g: in std_logic_vector(3 downto 0); g1 : out std_logic_vector(3 downto 0) ); end gray_inc;

100 Грејев бројач (2) architecture direct_arch of gray_inc is begin with g select g1 <= "0001" when "0000", "0011" when "0001", "0010" when "0011", "1001" when "1011", ... "1000" when "1001", "0000" when others; -- "1000" end direct_arch;

101 Грејев бројач (3) Нескалабилно
Алгоритам за опште инкрементирање Грејевог кода не постоји Други приступ Конвертовати у бинарни број Инкрементирати Вратити у Грејев код

102 Грејев бројач (4) architecture compact_arch of gray_inc is constant WIDTH: integer := 4; signal b, b1: std_logic_vector(WIDTH-1 downto 0); begin -- Gray to binary b <= g xor ('0' & b(WIDTH-1 downto 1)); -- binary increment b1 <= std_logic_vector((unsigned(b)) + 1); -- binary to Gray g1<= b1 xor ('0' & g1(WIDTH-1 downto 1)); end compact_arch ;

103 Атрибути сигнала S’delayed(T) – Сигнал S закашњен за T
S’stable(T) – Враћа тачно ако сигнал S у претходном интервалу T није мењао вредност S’quiet(T) – Враћа тачно ако на сигналу S у претходном интервалу T није било трансакција S’transaction – Сигнал који мења вредност из '0' у '1' и обрнуто сваки пут када се догоди трансакција сигнала S >Does anyone know what the difference between <signal>'event and ><signal>'transaction is? Anyone has a precise definition of these <sig>'event is a boolean value that is TRUE in a delta cycle when <sig> has just changed, and FALSE at other times. You can test 'event in an IF statement. Take, for example, the not-very-pretty traditional form of clocked process: process(clk, rst) begin if rst='1' then -- do reset actions elsif clk='1' and clk'event then -- clk has just changed to '1', and -- that change triggered the process -- so do clocked actions <sig>'transaction allows you to check whether some assignment was made to the signal, even if that assignment didn't change the signal's value. <sig>'transaction is a completely new signal, of type BIT, that toggles from '0' to '1' or back again in each delta cycle when one or more assignment is made to <sig>. This is occasionally useful if you have a data structure representing a transaction, and you would like to detect when someone puts a new value on that data structure - even if it's the same as the existing value. Because it's a new signal in its own right, you can use it in a sensitivity list... wait on thing'transaction; -- someone has written to "thing" -- so we need to process the new value

104 Атрибути сигнала S’event – Враћа тачно ако је у текућем симулационом циклусу дошло до догађаја на сигналу S S’active – Враћа тачно ако је у текућем симулационом циклусу дошло до трансакције на сигналу S S’last_event – Време од последњег догађаја S’last_active – Време од последње трансакције S’last_value – Вредност сигнала S пре последњег догађаја

105 Пример употребе атрибута
Провера да ли је задовољено setup време: if clk'event and (clk = '1' or clk = 'H') and (clk'last_value = '0' or clk'last_value = 'L') then assert d'last_event >= Tsu report "Timing error: d changed within setup time of clk"; end if; Провера да ли је улазни сигнал такта довољно мале фреквенције: assert (not clk'event) or clk'delayed'last_event >= Tpw_clk report "Clock frequency too high"; Tsu je setup time, znaci ako je doslo do promene za manje od toga, onda je greska

106 Наредба wait Обезбеђује могућност суспендовања догађаја до испуњења неког од услова: догађај на неком сигналу испуњења задатог логичког услова истека задатог временског интервала. Могућа и комбинација услова када се наредба тумачи на следећи начин: чекање је временски ограничено временом наведеним у for делу сваки пут када дође до догађаја на неком од сигнала у on делу проверава се услов; ако је испуњен наставља се даље. wait_statement <= [label:] wait [on signal_name{,...}] [until boolean_expression] [for time_expression] Услов се проверава: ако нема on клаузула: на сваки догађај било ког сигнала наведеног у услову, ако има on клаузула: сваки пут када дође до догађаја на неком од сигнала у on клаузули. wait on a, b; - aktivira proces na promenu a ili b wait until clk=‘1’ - aktivira proces kada clk postane ‘1’ wait on clk until reset=‘0’ - kada se promeni clk testira reset wait until trigger=‘1’ for 1ms - proces je suspendovan dok trigger ne postane 1 ilii dok ne prođe 1 ms

107 if-then-else Секвенцијални исказ.
Обезбеђује условно извршавање других секвенцијалних исказа. Условно извршавање је приоритирано; када се наиђе на први тачан услов, прекида се провера осталих. Могуће угнездити више if-then-else исказа. [ if_label : ] if uslov then { sekvencijalni_iskaz } { elsif uslov then {sekvencijalni_iskaz } } [ else {sekvencijalni_iskaz } ] end if [ if_label ] ;

108 Пример 1 if sel0 = '0' and sel1 = '0' then z<= d0; elsif sel0 = '1' and sel1 = '0' then z<= d1; elsif sel0 = '0' and sel1 = '1' then z<= d2; elsif sel0 = '1' and sel1 = '1' then z<= d3; end if;

109 Синтетизован модел примера 1
Пример 1 Конкурентна условна додела сигнала

110 Синтетизован модел примера 1 технолошки поглед

111 Пример 2 if sel0 = '0' and sel1 = '0' then z<= d0; elsif sel0 = '1' and sel1 = '0' then z<= d1; elsif sel0 = '0' and sel1 = '1' then z<= d2; else z<= d3; end if; Због постојања else никада не остаје стара вредност. Зато синтетизовани модел нема леч коло. Погодно за синтезу, али при тестирању може да прeкрије потенцијални проблем.

112 Синтетизован пример 2 RTL поглед

113 Пример 3 if sel0 = '0' and sel1 = '0' then z<= d0; elsif sel0 = '1' and sel1 = '0' then z<= d1; elsif sel0 = '1' and sel1 = '1' then z<= d3; end if;

114 Синтетизован пример 3 Пример 3
Примјер формирања секвенцијалног кола са конкурентном условном доделом вредности

115 Пример 4 if sel0 = '0' and sel1 = '0' then z<= d0; elsif sel0 = '1' and sel1 = '0' then z<= d1; elsе z<= d3; end if;

116 Синтетизован пример 4 Пример 4
Пример формирања секвенцијалног кола са конкурентном условном доделом вредности

117 Пример 5 if sel1 = '0' then if sel0 = '0' then z<= d0; else z<= d1; end if; else if sel0 = '0' then z<= d2; else z<= d3; end if; end if;

118 Синтетизован пример 5

119 Пример 6 Унутар било којег блока може да буде и више секвенцијалних наредби. if opcode = halt_opcode then PC := effective_address; executing := false; halt_indicator <= true; end if;

120 Условна додела променљивој
name := expression when condition { else expression when condition } [ else expression ] ; Појављује се тек у VHDL 2008 Пример: result := a - b when mode = subtract else a + b; Еквивалентно са: if mode = subtract then result := a - b; else result := a + b; end if;

121 CASE Секвенцијални исказ.
Омогућава извршавање одговарајућег низа исказа у зависности од вредности исказа. Извршава се само једна опција. Нема приоритета. Свака могућа вредност се у опцијама мора појавити тачно једном (погледати забeлешке уз слајд). [ case_label : ] case[?] izraz is ( when opcija => { sekvencijalni_iskaz } ) { … } end case [ case_label ] ; opcija ⇐ ( konstantan_izraz I diskretan_opseg I others ) { | … } Израз за селекцију (између case и is) се може конвертовати у одговарајући подтип ако се жели скратити скуп опција. naziv_podtipa'(izraz)

122 Пример 1 case func is when pass1 => result := operand1; when pass2 => result := operand2; when add => result := operand1 + operand2; when subtract => result := operand1 - operand2; end case;

123 Пример 2 case opcode is when load | add | subtract => operand := memory_operand; when store | jump | jumpsub | branch => operand := address_operand; when others => operand := 0; end case;

124 Пример 3 entity mux is port(d0, d1, d2, d3:in std_logic; sel:in std_logic_vector(1 downto 0); z:out std_logic); end entity; architecture dataflow of mux is begin process(d0, d1, d2, d3, sel)is begin case sel is when "00" => z <= d0; when "01" => z <= d1; when "10" => z <= d2; when "11" => z <= d3; end case; end process; end architecture;

125 Пример 4 type opcodes is (nop, add, subtract, load, store, jump, jumpsub, branch, halt); case opcode is when add to load => operand := memory_operand; when branch downto store => operand := address_operand; when others => operand := 0; end case;

126 Пример 5 type opcodes is (nop, add, subtract, load, store, jump, jumpsub, branch, halt); subtype control_transfer_opcodes is opcodes range jump to branch; when control_transfer_opcodes | store => operand := address_operand;

127 Пример нерегуларног case исказа
variable N : integer := 1; case expression is when N | N+1 => ... when N+2 to N+5 => ... when others => ... end case; Да је N константа, горњи исказ би био коректан.

128 Селекциона додела променљивој
with expression select[?] name := { expression when choices , } expression when choices ; Тек од VHDL 2008. Примјер: with func select result := operand1 when pass1, operand2 when pass2, operand1 + operand2 when add, operand1 - operand2 when subtract;

129 null исказ Начин да се специфицира да се у неком случају не дешава ништа case opcode is when add => Acc := Acc + operand; when subtract => Acc := Acc - operand; when nop => null; end case; control_section : process ( sensitivity_list ) is begin null; end process control_section;

130 assert i report Исказ намењен за помоћ при провери исправности модела. [ label : ] assert condition [ report expression ] [ severity expression ] ; Уколико се при симулацији деси да услов буде нетачан, генерише се обавештење; report клаузула омогућава да се прецизније опише место где је настала грешка, нпр.: assert current_character >= '0' and current_character <= '9' report "Input number " & input_string & " contains a non-digit"; Алат за синтезу може сматрати да ће услов бити тачан. severity: note – обавештење, warning – може се наставити али резултати могу бити неочекивани, error – грешка, потребно предузети акције за опоравак - подразумевано, failure – ситуација која се није смела догодити. report – исто као значење assert false... , али се пише без assert. подразумевано note.

131 Процедуре subprogram body <= procedure identifier [(parameter_interface_list)] is {subprogram_declarative_part} begin {sequential_statement} end [procedure] [identifier ]; Могу се декларисати у декларативном делу: пакета => видљива где год се користи тај пакет, архитектуре => видљива свим процесима, процеса => видљива само том процесу, други подпрограми=> видљива само у том подпрограму.

132 Пример procedure average_samples is variable total: real := 0.0; begin assert samples’length /= 0 severity failure; for index in samples’range loop total:= total + samples(index); end loop; average:= total/real(samples’length); end procedure average_samples;

133 Пример (1/3) architecture RTL of control_processor is type func_code is (add, subtract); signal op1, op2, dest: integer; signal Z_flag: boolean; signal func: func_code; ... begin ...

134 Пример (2/3) alu: process is procedure do_arith_op is variable result: integer; begin case func is when add => result:= op1 + op2; when sub => result:= op1 - op2; end case; dest <= result after Tpd; Z_flag <= result = 0 after Tpd; end procedure do_arith_op;

135 Пример (3/3) begin do_arith_op; ... end process alu; ... end architecture RTL;

136 Параметри потпрограма
interface_list <= ([constant | variable | signal] identifier {,...}: [mode] subtype_indication [:= static_expression]){,...} mode <= in | out | inout ; подразумевани мод: in. Подразумевано: in => constant out => variable inout => variable Од ВХДЛ 2008 дозвољено читање out параметара, али се добија последња уписана вриједност у процедури или ако још није додељена вредност, добија се почетна вредност.

137 Сигнали као параметри in: Процедура добија референцу на сигнал
Ако у процедури постоји wait iсказ, вредност сигнала се може променити. out: Процедури се прослеђује референца на драјвер сигнала Приликом доделе вредности сигналу унутар процедуре, дефинишу се трансакције за прослеђени сигнал. inout: прослеђују се и референца на сигнал и референца на драјвер

138 Позивање процедуре procedure_call_statement <= [label:] procedure_name [(parameter_association_list)]; parameter_association_list <= ([parameter_name =>] expression | signal_name | variable_name | open) {,...} Примјери: procedure p(f1: in t1; f2: in t2; out t3; f4: in t4:=v4) is begin end procedure p; poziv: p(val1, val2, val3, val4); poziv: p(f1 => val1, f2=> val2, f4=> val4, f3=> val3); poziv: p(val1, val2, f4 => open, f3 => val3); Ако се везивање врши по називу, аргументи се могу навести произвољним редом.

139 Конкурентни позив процедуре
concurrent_procedure_call_statement <= [label:] procedure_name [(parameter_association_list)]; Еквивалентно процесу који позива ту процедуру. Примјер: call_proc: p(s1, s2, 10) --s1, s2 сигнали call_proc: process is begin p (s1, s2, 10); wait on s1, s2; end process call_proc;

140 Функције subprogram body <= [pure | impure] function identifier [(parameter_interface_list)] return type_mark is {subprogram_declarative_part} begin {sequential_statement} end [function] [identifier ]; pure => резултат зависи само од параметара за исте аргументе увијек враћа исту вредност. Подразумијевано pure.

141 Параметри функција Исто као код процедура, осим:
сви параметри морају бити типа in класа параметра не може бити променљива. in – подразумевани смер constant – подразумевана класа параметра.

142 Пример function limit(value,min,max:integer) return integer is begin if value > max then return max; elsif value <min then return min; else return value; end if; end function limit;

143 Функција now now враћа тренутно време. Примјер употребе:
hold_time_checker : process ( clk, d ) is variable last_clk_edge_time : time := 0 fs; begin if rising_edge(clk) then last_clk_edge_time := now; end if; if d'event then assert now - last_clk_edge_time >= Thold_d_clk report "hold time violation"; end process hold_time_checker;

144 Преклапање потпрограма
Више потпрограма истог назива различитог броја и/или типа параметара. procedure increment (a:inout integer, n:in integer:=1) is ... procedure increment (a:inout bit_vector, n:in bit_vector :=1) is ... procedure increment (a:inout bit_vector, n: in integer:=1) is ...

145 Преклапање оператора function “+” (left, right: in bit_vector) return bit_vector is begin ... end function “+”; addr_reg:= addr_reg + X”0000_0004”;

146 Видљивост декларација
Свака декларативна секција има одговарајућу секцију за исказе. Свака декларација се види од мјеста декларисања до краја одговарајуће секције за исказе.

147 Пакети Обједињују заједничке типове, константе, сигнале и потпрограме.
package_declaration <= package identifier is {package_declarative_item} end [package] [identifier]; package_body <= package body identifier is {package_body_declarative_item} end [package body] [identifier];

148 Пример декларације пакета
package cpu_types is constant word_size: positive:= 16; constant address_size: positive:= 24; subtype word is bit_vector(word_size-1 downto 0); subtype address is bit_vector(address_size-1 downto 0); type status_value is (halted, idle, fetch, mem_read, mem_write, io_read, io_write, int_ack); end package cpu_types;

149 Пример коришћења пакета
Пакет се одвојено анализира и након тога смешта у радну библиотеку. (зависи од алата) Пример коришћења: entity address_decoder is port (addr: in work.cpu_types.address; status: in work.cpu_types.status_value; mem_sel, int_sel, io_sel: out bit); end entity address_decoder;

150 use use_clause <= use selected_name {,...};
selected_name <=naziv_biblioteke.naziv_paketa. (identifier | character_literal | operator_symbol | all) Примјер: use work.cpu_types.word, work.cpu_types.address; ... variable data_word: word; variable next_address: address; Примјер: use work.cpu_types.all; Sva imena iz paketa postaju vidljiva

151 Видљивост увезених идентификатора
Стандардно: виде се у декларативној секцији у којој су увезени и одговарајућој секцији за исказе. Увезени на почетку фајла => виде се до краја фајла. Увезени испред ентитета (или пакета) => виде се и у одговарајућој архитектури (односно телу пакета). Конфликт са локалним идентификатором => директно видљив само локални глобалном се приступа преко пуног назива. Конфлит два увезена: имплицитни и експлицитни оператор => види се експлицитни у супротном ништа није директно видљив. Функције које могу да се преклопе => нема конфликта.

152 alias alias_declaration <= alias identifier is name; Примјери:
alias alu_data_width is work.alu_types.data_width; Могуће је дефинисати и алијасе и за типове: alias binary_string is bit_vector; и за потпрограме: procedure increment (bv: inout bit_vector, by: in integer:= 1) alias bv_increment is work.ops.increment[bit_vector, integer]

153 Примери type register_array is array (0 to 15) of bit_vector(31 downto 0); type register_set is record general_purpose_registers: register_array; program_counter: bit_vector(31 downto 0); program_status: bit_vector(31 downto 0); end record; variable CPU_registers: register_set; alias PSW is CPU_registers.program_status; alias PC is CPU_registers.program_counter; alias GPR is CPU_registers.general_purpose_registers;

154 Разрешени сигнали Користе се када за један сигнал има више драјвера који генеришу његову вредност. Служи искључиво за потребе симулације за моделовње ситуација које није могуће моделовати са две вредности. Пример: моделовање стања високе импедансе type tri_state_logic is (‘0’, ‘1’, ‘Z’); type tri_state_logic_array is array (integer range<>) of tri_state; signal s: resolve_tri_state_logic tri_state_logic; Испред сигнала се наводи функција за разрешавање Приликом доделе нове вредности сигналу, позива се функција којој се као параметар прослеђује низ драјвера. Резултат позване функције се додељује сигналу.

155 Пример функције за разрешавање
function resolve_tri_state_logic (values: in tri_state_array) return tri_state_logic is variable result: tri_state_logic:= ‘Z’; begin for index in values’range loop if values(index) /= ‘Z’ then result:= values(index); end if; end loop; return result; end function resolve_tri_state_logic; Која претпоставка мора важити да би функција дала очекивани резултат?

156 Пример разрешеног подтипа (1/2)
type MLV4_ulogic is (‘X’, ‘0’, ‘1’, ‘Z’); type MLV4_ulogic_vector is array (natural range <>) of MVL4_ulogic; function resolve_MVL4 (contribution: MVL4_ulogic_vector) return MVL4_ulogic sybtype MVL4_logic is resolve_MVL4 MVL4_ulogic; type table is array (MVL4_ulogic, MVL4_ulogic) of MVL4_ulogic; constant resolution_table: table:= -- ‘X’ ‘0’ ‘1’ ‘Z’ (( ‘X’, ‘X’, ‘X’, ‘X’), -- ‘X’ ( ‘X’, ‘0’, ‘X’, ‘0’), -- ‘0’ ( ‘X’, ‘X’, ‘1’, ‘1’), -- ‘1’ ( ‘X’, ‘0’, ‘1’, ‘Z’)) -- ‘Z’

157 Пример разрешеног подтипа (2/2)
function resolve_MVL4 (contribution: MVL4_ulogic_vector) return MVL4_ulogic is variable result: MVL4_ulogic := 'Z' begin for index in contribution’range loop result:= resolution_table(result, contribution(index)); end loop; return result; end function resolve_MVL4;

158 Разрешавање вектора sybtype MVL4_logic_vector is (resolve_MVL4) MVL4_ulogic_vector; Заграде око функције за разрешавање говоре да се она примјењује на елементе вектора, а не на читав вектор. Могуће је имати и већи број заграда нпр. ако се разрешавају елементи матрице, користе се две заграде.

159 Разрешавање std_ulogic

160 Комбинационе vs. Секвенцијалне мреже

161 D latch временски параметри

162 DFF временски параметри

163 Синхроне vs. Асинхроне мреже
Глобално синхроне мреже Сви меморијски елементи активни на ивицу једног сигнала клока Глабално асинхроне локално синхроне мреже Глобално асихнроне мреже Сви меморијски елементи имај свој клок Нема клока

164 Синхроне мреже Синтеза се своди на синтезу комбинационих мрежа
Временска ограничења Један од најтежих проблема Временска анализа захтева само анализу комбинационих мрежа и једне повратне петље Симулација помоћу циклуса Тестирање помоћу “scan” алгоритама

165 Асинхроне мреже Комбинационе мреже са повратним везама
Другачији дизајн у односу на комбинационе мреже Осетљиве на кашњење

166 Асинхроне мреже - пример
library ieee; use ieee.std_logic_1164.all; entity dlatch is port( c: in std_logic; d: in std_logic; q: out std_logic ); end dlatch;

167 Асинхроне мреже - пример
architecture demo_arch of dlatch is signal q_latch: std_logic; begin process (c, d, q_latch) if (c = '1') then q_latch <= d; else q_latch <= q_latch; end if; end process; q <= q_latch; end demo_arch;

168 Асинхроне мреже - пример

169 D FF library ieee; use ieee.std_logic_1164.all; entity dff is port(
clk: in std_logic; d: in std_logic; q: out std_logic ); end dff;

170 D FF architecture demo_arch of dff is begin process (clk)
if (clk’event and clk = '1') then q <= d; end if; end process; end demo_arch;

171 Register entity register8 is port(clk,reset:in std_logic; d:in std_logic_vector(7 downto 0); q:out std_logic_vector(7 downto 0) ); end entity register8;

172 Register architecture reg of register8 is begin process (clk, reset) is if (reset = '1') then q <= (others => '0'); elsif (clk'event and clk = '1') then q <= d; end if; end process write; end;

173 Проста секвенцијална кола

174 DFF са Enable сигналом

175 DFF са Enable сигналом library ieee; use ieee.std_logic_1164.all; entity dff is port( clk, reset, en: in std_logic; d: in std_logic; q: out std_logic ); end dff;

176 DFF са Enable сигналом architecture demo_arch of dff is signal q_reg, q_next : std_logic; begin process (clk, reset) if (reset = '1') then q_reg <= '0'; elsif (clk’event and clk = '1') then q_reg <= q_next; end if; end process;

177 DFF са Enable сигналом -- next-state logic q_next <= d when en = '1' else q_reg; -- output-state logic q <= q_reg; end demo_arch;

178 Shift register

179 Shift register

180 Shift register

181 Shift register Операције Учитавање Померање улево Померање удесно
Задржавање старе вредности

182 Shift register library ieee; use ieee.std_logic_1164.all; entity shift_register is port(clk,reset:in std_logic; ctrl:in std_logic_vector(1 downto 0); d:in std_logic_vector(3 downto 0); q:out std_logic_vector(3 downto 0) ); end entity shift_register;

183 Shift register architecture usr of shift_register is signal r_reg: std_logic_vector(3 downto 0); signal r_next: std_logic_vector(3 downto 0); begin process (clk, reset) is if (reset = '1') then r_reg <= (others => '0'); elsif (clk'event and clk = '1') then r_reg <= r_next; end if; end process;

184 Shift register with ctrl select r_next <= r_reg when "00", r_reg(2 downto 0) & d(0) when "01", d(3) & r_reg(3 downto 1) when "10", d when others; q <= r_reg; end usr;

185 Алтернатива Мешање кода за меморијске елементе и комбинациону логику у једном или више процеса За проста кола код може да буде елегантнији Обично се стварају неочекиване грешке Избегавати!!!

186 Променљиве Могу да се користе за моделирање меморијских елемената
Локална за процес Додела вредности променљивој пре употребе Не захтева прављење меморијског елемнта Коришћење променљиве пре доделе Захтева прављење меморијског елемента Лако је направити грешку Најчешћа употреба Смештање међурезултата без прављења меморијских елемената

187 Променљиве - пример library ieee; use ieee.std_logic_1164.all; entity variable_demo is port(clk:in std_logic; a,b:in std_logic; q1, q2, q3:out std_logic ); end entity variable_demo;

188 Променљиве - пример architecture arch of variable_demo is signal tmp_sig1: std_logic; begin -- atempt 1 process (clk) if (clk'event and clk = '1') then tmp_sig1 <= a and b; q1 <= tmp_sig1; end if; end process;

189 Променљиве - пример -- atempt 2 process (clk) variable tmp_var2:std_logic; begin if (clk'event and clk = '1') then tmp_var2 := a and b; q2 <= tmp_var2; end if; end process; end arch;

190 Променљиве - пример -- atempt 3 process (clk) variable tmp_var3:std_logic; begin if (clk'event and clk = '1') then q3 <= tmp_var3; tmp_var3 := a and b; end if; end process; end arch;

191 Променљиве - пример

192 Register transfer (RT) моделовање
Како реализовати алгоритам у хардверу? Две одлике алгоритама: Коришћење променљивих Секвенцијално извршавање

193 Register transfer (RT) моделовање
Пример алгоритма: Сабирање 4 броја Дељење резултата са 8 Заокруживање резултата

194 Dataflow Имплементација у VHDL-у
Конвертован алгоритам у комбинациону мрежу Нема меморијских елемената Секвенца је одређена током података

195 Dataflow

196 Dataflow

197 Dataflow Проблеми: Лако за тривијалне алгоритме Није флексибилно
Број улазних елемената треба да се повећа Број улазних елемената треба да буде произвољан

198 RT моделовање Користити регистре за имитирање променљивих из алгоритма
Користити ток података за реализацију свих регистарских операција Користити КА-те за одређивање редоследа регистарских операција

199 RT операције Основна форма Интерпретација:
После узлазне ивице сигнала такта, излази изворишних регистара су спремни Излази се прослеђују комбинационој мрежи која врши произвољну функцију На следећу ивицу сигнала такта, резултат се смешта у дестинациони регистар

200 RT операције Пример: r ← 1 r ← r r0 ← r1 n ← n - 1
y ← a xor b xor c xor d s ← a2 + b2

201 RT пример имплементације
r1 ← r1 + r2

202 KA као контролна јединица
КА је добар као контролна јединица за RT операције Стања се мењају на сваки сигнал такта КА може да омогући секвенцијално извршавање КА дозвољава опције (гранање) Дијаграм тока добар за репрезентовање контролне јединице

203 RT систем

204 GCD коло - пример GCD – Највећи заједнички делилац GCD без дељења
gcd(a, b) = a if a = b gcd(a – b, b) if a = b gcd(a, b - a) if a = b

205 GCD коло - пример Псеудо алгоритам a = a_in; b = b_in;
while (a /= b) { if (b > a) then a = a – b; else b = b – a; end if } r = a;

206 GCD коло - пример Модификован псеудо алгоритам a = a_in; b = b_in;
swap: if (a = b) then goto stop; else if (b > a) then a = b; --swap a and b b = a; end if; a = a – b; goto swap; stop: r = a;

207 Дијаграм тока

208 Инстанцирање ентитета
component_instantiation_statement <= instantiation_label: entity entity_name [(architecture_identifier)] [generic map (generic_association_list)] [port map (port_association_list)]; port_association_list <= ([port_name =>] (signal_name|expression|open)) {, ...} open – означава да порту није придружен сигнал. Уколико се наведу називи портова, редослед није битан. Пре ВХДЛ 2008 израз је морао бити статички => израчунати одговарајући израз као конкурентни исказ доделе вредности сигналу и тај сигнал мапирати на порт.

209 Пример entity DRAM_controller is port (rd, wr, mem: in bit; ras, cas, we, ready: out bit); end entity DRAM_controller; mem_controller: entity work.DRAM_controler (fpld) port map (cpu_rd, cpu_wr, cpu_mem, mem_ras, mem_cas, mem_we, cpu_rdy) mem_controller: entity work.DRAM_controler (fpld) port map (rd => cpu_rd, wr =>cpu_wr, mem => cpu_mem, ras => mem_ras, cas => mem_cas, we => mem_we, ready => cpu_rdy)

210 Компоненте Декларација vs дефиниција.
Могуће их је декларисати и у пакетима. тада се у декларативном делу архитектуре увози назив компоненте (USE naziv_paketa.naziv_komponente). component_declaration <= component identifier [is] [generic (generic_interface_list);] [port (port_interface_list);] end component [identifier]; Primer: component flipflop is generic (Tprop, Tsetup, Thold: delay_lenght); port (clk: in bit; clr: in bit; q: out bit); end component flipflop;

211 Инстанцирање компонената
component_instantiation_statement <= instantiation_label: [component] component_name [generic map (generic_association_list)] [port map (port_association_list)]

212 Пример (1/2) entity reg4 is port (clk, clr: in bit, d: in bit_vector(0 to 3), q: out bit_vector (0 to 3)); end entity reg4; architecture struct of reg4 is component flipflop is generic (Tprop, Tsetup, Thold: delay_lenght); port (clk: in bit; clr: in bit; q: out bit); end component flipflop; ...

213 Пример (2/2) ... begin bit0: component flipflop generic map (Tprop=>2ns, Tsetup=>2ns, Thold=>1ns) port map (clk=>clk, clr=>clr, d=>d(0), q=>q(0)); bit1: component flipflop generic map (Tprop=>2ns, Tsetup=>2ns, Thold=>1ns) port map (clk=>clk, clr=>clr, d=>d(1), q=>q(1)); ... end;

214 Конфигурисање компонената
Свака компонента може имати више реализација => Конфигурацијом се компоненте везују за жељене ентитете. configuration_declaration <= configuration identifier of entity_name is for architecture_name {for component_specification binding_indication; end for;} end for; end [configuration] [identifier]; component_specification ⇐ ( instantiation_label { , … } I others I all ) : component_name binding_indication ⇐ use entity entity_name[(architecture_identifier ) ] Називи портова компоненте и ентитета за који се везује се морају поклапати.

215 Пример configuration reg4_gate_level of reg4 is for struct -- architecture of reg4 for bit0: flipflop use entity edge_triggered_Dff(hi_fanout); end for; for others: flipflop use entity edge_trigerd_Dff(basic); end for; end for; end of architecture struct end configuration reg4_gate_level;

216 Конфигурисање компонената
Ако се компонента везује са ентитетом за који је такође потребна конфигурација, тада се при везивању уместо: use entity naziv_entiteta koristi: use configuration naziv_konfiguracije Могуће је и угнездити конфигурације, није прегледан => не препоручује се. Могуће директно инстанцирати конфигурације: instantiation_label : configuration configuration_name [ generic map ( generic_association_list ) ] [ port map ( port_association_list ) ] ;

217 Пример configuration counter_down_to_gate_level of counter is for registered for all : digit_register use configuration work.reg4_gate_level; end for; bindings for other component instances end for; -- end of architecture registered end configuration counter_down_to_gate_level;

218 Конфигурисање Омогућава ремапирање портова и генеричких константи, као и прилагођавање ентитета компонентама binding_indication ⇐ use (entity entity_name [(architecture_identifier )] I configuration configuration_name ) [ generic map ( generic_association_list ) ] [ port map ( port_association_list ) ]

219 Пример (1/3) architecture structure of computer_system is component decoder_2_to_4 is generic ( prop_delay : delay_length ); port ( in0, in1 : in bit; out0, out1, out2, out3 : out bit ); end component decoder_2_to_4; ... begin interface_decoder : component decoder_2_to_4 generic map ( prop_delay => 4 ns ) port map ( in0 => addr(4), in1 => addr(5), out0 => interface_a_select, out1 => interface_b_select, out2 => interface_c_select, out3 => interface_d_select ); end architecture structure;

220 Пример (2/3) Уместо декодера 2 на 4 имамо 3 на 8:
entity decoder_3_to_8 is generic ( Tpd_01, Tpd_10 : delay_length ); port ( s0, s1, s2 : in bit; enable : in bit; y0, y1, y2, y3, y4, y5, y6, y7 : out bit ); end entity decoder_3_to_8;

221 Пример (3/3) configuration computer_structure of computer_system is for structure for interface_decoder : decoder_2_to_4 use entity work.decoder_3_to_8(basic) generic map ( Tpd_01 => prop_delay, Tpd_10 => prop_delay ) port map ( s0 => in0, s1 => in1, s2 => '0', enable => '1', y0 => out0, y1 => out1, y2 => out2, y3 => out3, y4 => open, y5 => open, y6 => open, y7 => open ); end for; ... end configuration computer_structure;

222 Одложено везивање Користи се у сложеном дизајну када је потребно тестирати један део система који је тренутно завршен. binding_indication ⇐ use open

223 Генерисање структура Користе се у случају репликације компонената.
for_generate_statement ⇐ generate_label : for identifier in discrete_range generate generate_statement_body end generate [ generate_label ] ; generate_statement_body ⇐ [ { block_declarative_item } begin ] { concurrent_statement } [ end ; ]

224 Пример (1/3) Описати регистар генеричке ширине.
entity register_tristate is generic (width: positive); port (clock: in std_logic; out_enable: in std_logic; data_in: in std_logic_vector(0 to width-1); data_out: out std_logic_vector(0 to width-1); end entity register_tristate;

225 Пример (2/3) architecture cell_level of register_tristate is component D_flipflop is port (clk, d: in std_logic; q: out std_logic); end component D_flipflop; component tristate_buffer is port (a, en: in std_logic; y: out std_logic); end component tristate_buffer;

226 Пример (3/3) begin cell_array: for bit_index in 0 to width-1 generate signal data_unbuffered: std_logic; begin cell_storage: component D_flipflop port map (clk=> clock, d=>data_in(bit_index), q=>data_unbaffered); cell_storage: component tristate_buffer port map (a=> data_unbaffered, en=>out_enable, y=>data_out(bit_index)); end generate cell_array; end architecture cell_level;

227 Условно генерисање структура
if_generate_statement ⇐ generate_label : if [alternative_label :] condition generate generate_statement_body { elsif [alternative_label :] condition generate generate_statement_body } [ else [alternative_label :] generate generate_statement_body ] end generate [ generate_label ] ; elsif i else су присутни тек у VHDL-2008.

228 Конфигурисање генерисаних компоненти
block_configuration ⇐ for ( architecture_name I block_statement_label I generate_statement_label [ ( ( static_discrete_range I static_expression I alternative_label ) ) ] ) { block_configuration I for component_specification [ binding_indication ; ] [ block_configuration ] end for ; } end for ;

229 Пример configuration widget_cfg of arith_unit is for ripple_adder for adder for adder_cell(most_significant) for add_bit: full_adder use entity widget_lib.full_adder(asic_cell); end for; for adder_cell(middle) for adder_cell(least_significant) for add_bit: half_adder use entity widget_lib.half_adder(asic_cell); end for; -- adder end for; -- ripple_adder end configuration widget_cfg; adder: for i in width-1 downto 0 generate signal carry_chain : unsigned(width-1 downto 1); begin adder_cell: if most_significant: i = width-1 generate add_bit: component full_adder port map (...); elsif least_significant: i = 0 generate add_bit: component half_adder else middle: generate end generate adder_cell; end generate adder;

230 Ентитет и конкурентни искази
entity identifier is [ generic (generic_interface_list);] [ port (port_interface_list);] {entity_declarative_item} [begin { concurrent_assertion_statement | passive_concurrent_procedure_call_statement | passive_process_statement } ] end [entity] [identifier];

231 Пример Опис SR леч кола:
entity S_R_flipflop is port (s, r: in; q, q_n: out bit); begin check: assert not (s=‘1’ and r=‘1’) report “Incorrect use: s and r both ‘1’”; end entity and2;

232 register i bus signal_declaration ⇐
signal identifier { , … } : subtype_indication [ register I bus ] [ := expression ] ; Морају бити разрешени сигнали. register – дисконектовани сви драјвери => памти се последња вредност bus – дисконектовани сви драјвери => позива се функција за разрешавање са празним низом драјвера

233 Фајлови и улаз/излаз Дефинисање типа фајла: Пример: Дефинисање фајла:
file_type_definition ⇐ file of type_mark Пример: type integer_file is file of integer; Дефинисање фајла: file identifier { , … } : subtype_indication [ [ open file_open_kind_expression] is "naziv_fajla"]; type file_open_kind is (read_mode, write_mode, append_mode); подразумевано za фајлове на диску: read_mode.

234 Отварање фајла Ако је при дефиницији наведено open:
Ако се фајл дефинише у пакету, архитектури или процесу => отвара се имплицитно на почетку симулације, затвара се имплицитно на крају симулације. Ако се фајл дефинише у потпрограму => отвара се приликом позива потпрограма, затвара се приликом повратка из потпрограма. У супротном, отвара се и затвара експлицитно: Отварање procedure file_open ( file f : file_type; external_name : in string; open_kind : in file_open_kind := read_mode ); Затварање procedure file_close ( file f : file_type );

235 Читање из фајла Имплицитно дефинисане функције:
procedure read ( file f:file_type; value:out element_type ); function endfile ( file f : file_type ) return boolean; Читање почиње од почетка. Након читања, текућа позиција се помера.

236 Пример (1/3) library ieee; use ieee.std_logic_1164.all; entity ROM is generic ( load_file_name : string ); port ( sel : in std_ulogic; address : in std_ulogic_vector; data : inout std_ulogic_vector ); end entity ROM; Иницијализовање ром меморије.

237 Пример (2/3) architecture behavioral of ROM is begin behavior : process is subtype word is std_ulogic_vector(0 to data'length - 1); type storage_array is array (natural range 0 to 2**address'length - 1) of word; variable storage : storage_array; variable index : natural; other declarations type load_file_type is file of word; file load_file : load_file_type open read_mode is load_file_name;

238 Пример (3/3) begin -- load ROM contents from load_file index := 0; while not endfile(load_file) loop read(load_file, storage(index)); index := index + 1; end loop; -- respond to ROM accesses loop ... end process behavior; end architecture behavioral;

239 Упис у фајл Користи се да се резултати симулације сачувају у фајл. Нпр.: мерење фреквенције појединих инструкција, утицај параметара дизајна на перформансе, ... По отварању фајла за упис, креира се нови фајл; ако је већ постојао истоимени фајл, биће обрисан. Процедура за упис: procedure write ( file f : file_type; value : in element_type ); Ако је фајл отворен у моду append, дописује се на крај фајла. Ако фајл не постоји, биће креиран нови. Омогућава акумулацију резултата низа симулација.

240 Преносивост Претходно описани фајлови су бинарни фајлови.
За бинарне фајлове, начин кодирања података у фајлу зависи од алата и система. Решење => користити текстуалне фајлове.

241 Пакет textio Користи се показивач на стринг:
type line is access string; Дефинисан је тип текстуалног фајла: type text is file of string; Тип за дефинисање поравнања: type side is (right, left); Тип за ширину поља приликом исписа: subtype width is natural; Предефинисани су фајлови за стандардни улаз и излаз: file input : text open read_mode is "STD_INPUT"; file output : text open write_mode is "STD_OUTPUT"; access – показивач

242 Читање из текстуалног фајла
Алоцира стринг, учита једну линију у тај стринг и кроз L враћа показивач на учитану линију: procedure readline(file F: text; L: inout line); Потом се користи нека од функција за конверзију. Важи за све: ако је читање успешно, из стринга се брише прочитано, варијанте са 2 и 3 параметра, разликују се у случају неуспеха, верзија са два параметра пријављује грешку ако читање није успело; сви подаци остају неизмењени, трећи параметар се поставља на нетачно у случају неуспелог читања; коришћени подаци остају неизмењени. Функције за читање знакова: procedure read ( L : inout line; value: out character; good : out boolean ); procedure read ( L : inout line; value: out character );

243 Читање стрингова procedure read ( L : inout line; value: out string );
чита тачно онолико знакова колики је одредишни стринг; ако нема довољно знакова, читање је неуспешно. procedure sread ( L: inout line; value : out string; strlen: out natural); прескаче бланко знакове на почетку; чита највише онолико континуалних небланко знакова колико стаје у стринг; у strlen враћа број учитаних знакова. Пример за стринг већичине 4 знака: ако је садржај линије " st ring ", биће учитано st

244 Конверзија у бите Конверзија у бит:
procedure read ( L : inout line; value: out bit ); Конверзија у бит вектор: ако стринг садржи бинарно записане векторе: procedure read ( L : inout line; value: out bit_vector ); alias bread is read [line, bit_vector]; ако стринг садржи хексадецимално записане векторе: procedure hread ( L: inout line; value: out bit_vector ); У оба случаја у фајлу је константа без ознаке основе. За std_logic постоје одговарајуће функције у пакету ieee.std_logic_textio. При читању хексадецимално записаног вектора, највиши бити се одбацују и морају бити 0. Као део вектора може да се нађе и доња црта.

245 Читање времена и бројева
Читање времена: procedure read ( L : inout line; value: out time ); Време мора бити записано са размаком између броја и јединице времена Читање целих бројева: procedure read ( L : inout line; value: out integer );

246 Универзални тест Процес који улазне тест векторе чита из фајла.
Могуће је извршити низ различитих симулација са истим testbench-ом мењајући само улазни фајл => нема потребе за рекомпилацијом. Пример улазног фајла: 0 ms on 2 ms fail 15 ms temp 56 100 ms set 1.5 sec on

247 Пример – "универзални тест"
stimulus_interpreter : process is use std.textio.all; file control : text open read_mode is "control"; variable command : line; variable read_ok : boolean; variable next_time : time; variable whitespace : character; variable signal_id : string(1 to 4); variable temp_value, set_value : integer; variable on_value, fail_value : bit;

248 Пример – "универзални тест"
command_loop : while not endfile(control) loop --čitanje jedne linije iz fajla readline ( control, command ); --čitanje trenutka kada treba da se izvrši promena read ( command, next_time, read_ok ); if not read_ok then report "error reading time from line: " & command.all severity warning; next command_loop; end if; wait for next_time - now;

249 Пример – "универзални тест"
--preskakanje blanko znakova while command'length > 0 and ( command(command'left) = ' ' or command(command'left) = ' ' --non breaking space or command(command'left) = HT ) loop read ( command, whitespace ); end loop; -- čitanje naziva signala read ( command, signal_id, read_ok ); if not read_ok then report "error reading signal id from line: " & command.all severity warning; next command_loop; end if;

250 Пример – "универзални тест"
-- dispatch based on signal id case signal_id is when "temp" => read ( command, temp_value, read_ok ); if not read_ok then report "error reading temperature value from line: " & command.all severity warning; next command_loop; end if; temperature <= temp_value; when "set " => ... – slično prethodnom

251 Пример – "универзални тест"
when "on " => read ( command, on_value, read_ok ); if not read_ok then report "error reading on value from line: " & command.all severity warning; next command_loop; end if; enable <= on_value; when "fail" => ... – slično prethodnom when others => report "invalid signal id in line: " & signal_id severity warning; end case; end loop command_loop; wait; end process stimulus_interpreter;

252 Упис у текстуални фајл Прво се изврши конверзија из задатог типа у линију, па се потом линија упише у фајл. Упис само у задати фајл: procedure writeline ( file F : text; L : inout line ); Упис у задати фајл и на стандардни излаз: procedure tee ( file F: text; L: inout line ); Ако је L = null, на излаз се исписује празна линија.

253 Упис у текстуални фајл function justify ( value: string; justified: side := right; field: width := 0 ) return string; стринг value се у новом стрингу ширине width поравнава уз задату ивицу; остатак резултујућег стринга се попуњава бланко знацима аналогно важи и за остале процедуре, с тим што се резултујући стринг надовезује на крај линије. procedure write ( L : inout line; value : in bit; justified: in side := right; field: in width := 0 ); procedure write ( L : inout line; value : in bit_vector; justified: in side := right; field: in width := 0 ); procedure hwrite ( L: inout line; value: in bit_vector; justified: in side := right; field: in width := 0 ); procedure write ( L : inout line; value : in time; justified: in side := right; field: in width := 0; unit: in time := ns );

254 Упис у текстуални фајл procedure write ( L : inout line; value : in string; justified: in side := right; field: in width := 0 ); alias swrite is write [line, string, side, width]; alias bwrite is write [line, bit_vector, side, width]; procedure write ( L : inout line; value : in integer; justified: in side := right; field: in width := 0 ); Приликом уписа константи типа string или bit_vector неопходно је навести тип константе. Примјер: write ( L, string'( "fred" ) ); write ( L, ' ' ); write ( L, bit_vector'( X"3A" ) ); Садржај резултујуће линије ако је на почетку линија била празна: fred


Download ppt "Увод у VHDL."

Similar presentations


Ads by Google