izvjestaj_projektni

28
ЕЛЕКТРОТЕХНИЧКИ ФАКУЛТЕТ УНИВЕРЗИТЕТ У БАЊОЈ ЛУЦИ ПРОЈЕКТОВАЊЕ ДИГИТАЛНИХ СИСТЕМА Студент: Савић Филип Број индекса: 1201/10 Предметни наставник: проф. др Бранко Докић Предметни асистент: Велибор Шкобић Број бодова: Бања Лука Јануар, 2014. године

Upload: filip-savic

Post on 03-Dec-2015

214 views

Category:

Documents


1 download

DESCRIPTION

A simple microprocessor in VHDL.

TRANSCRIPT

Page 1: Izvjestaj_projektni

Е Л Е К Т Р О Т Е Х НИ Ч К И ФАК У Л Т Е Т

У Н ИВ Е Р З И Т Е Т У Б АЊО Ј Л УЦ И

ПРОЈЕКТОВАЊЕ ДИГИТАЛНИХ СИСТЕМА

Студент: Савић Филип

Број индекса: 1201/10

Предметни наставник: проф. др Бранко Докић

Предметни асистент: Велибор Шкобић

Број бодова:

Бања Лука

Јануар, 2014. године

Page 2: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 2 -

ЈЕДНОСТАВАН МИКРОПРОЦЕСОРСКИ СИСТЕМ

Савић Филип E-mail: [email protected]

1. ДЕФИНИСАЊЕ ПРОЈЕКТА

Пројектни задатак састоји се од

реализације микропроцесорског система који

се састоји од једноставног

микропроцесорског елемента,који је у

могућности да очитава инструкције из

меморије и извршава их, програмабилног

тајмера и једног излазног порта.

Микропроцесор подржава рад са прекидима.

Као провјера функционалности самог

микропроцесора, систем треба да

комплементује стање излазног порта сваке

секунде. Мјерење времена је засновано на

прекидима које генерише тајмер. Системски

сат је фреквенције 27 MHz .

2. СПЕЦИФИКАЦИЈА

2.1. Спецификација софтвера

За реализацију пројектног задатка кориштен

је Quartus II 13.0 програмски пакет, као и

софтвер за симулацију Мodel Sim-Altera 10.0.

2.2. Спецификација хардвера

За реализацију пројекта кориштено је

развојно окружење DE1 произвођача Altera у

оквиру које се налази FPGA компонента

Cyclone II.

На слици 1 дати су искориштени

ресурси при реализацији.

Сл. 1 Искориштени ресурси

3. ОПИС ДИЗАЈНА

3.1. Увод

Циљ пројектног задатка је

реализовање основних функционалности

једноставног микропроцесорског система и

дефинисање базе која се на релативно

једноставан начин може надограђивати.

Обзиром да се реализовани систем

може сматрати претходником једног

комплекснијег система, у њему постоји

много недостатака који се, прије свега,

огледају у редукованом броју инструкција,

интерних модула и периферија. Међутим,

систем је конципиран на начин да је његово

проширење релативно једноставан задатак

који захтијева минималне корекције

реализованих модула.

3.2. Дијаграм тока извршавања

Пројект је конципран тако да се

састоји из 2 дијела:

1. Машина стања

2. Интерни модули

Улога машине стања је генерисање

неопходних управљачких сигнала за

комплетан систем, а сам концепт машине

стања је погодан због тачно утврђеног

редослиједа операција кроз које процесор

пролази при извршавању инструкција.

Сљедећа фаза у реализацији је

пројектовање интерних модула који ће

заједно са управљачком јединицом

(машином стања),посредством системске

магистрале, бити инкорпорирани у

јединствен систем. Када пројектант уочи да

је број потребних модула довољан за

одређену фунцкију, преостаје дате модуле

повезати и тестирати комплетан систем.

Дијаграм тока је представњен на слици 2:

Page 3: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 3 -

ДА

НЕ

НЕ

ДА

Сл.2 Дијаграм тока

3.3. Остали дијаграми

На слици 1 дата је блок шема

комплетног система.

Сл.1. Блок шема система

Уочава се 9 модула(слијева на десно

одозго на доле):

1. Аритметичко-логичка јединица

2. Адресни декодер

3. Инструкциони регистар

4. Тајмер

5. CPU (машина стања)

6. Показивач стека

7. Статусни порт

8. RAM

9. Програмски бројач

Функције појединих модула ће бити

објашњене у току извјештаја.

Такође, може се уочити да су сви

модули система повезани 12-битном

системском магистралом (sysbus). Стога се

може рећи да је реализовани систем 12-

битни.

На наредним сликама биће приказани

RTL дијаграми свих модула.

КОНЦИПИРАЊЕ СИСТЕМА

КОНСТРУКЦИЈА МАШИНЕ

СТАЊА

РЕАЛИЗОВАЊЕ ИНТЕРНИХ

МОДУЛА

Потребни

нови модули?

ПОВЕЗИВАЊЕ МОДУЛА У

СИСТЕМ

ТЕСТИРАЊЕ

СИСТЕМА(ВЕРИФИКАЦИЈА)

КРАЈ

Систем

задовољава

спецификације

?

МОДИФИКАЦ-

ИЈЕ

Page 4: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 4 -

Сл.1. Блок шема модула sequencer

Сл.2. Блок шема модула stack_pointer(SP)

Сл.3. Блок шема модула status_port

Сл.4. Блок шема модула timer

Сл.5. Блок шема модула ALU

Сл.6. Блок шема модула decoder

Page 5: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 5 -

Сл.7. Блок шема модула IR(Instruction Register)

Сл.8. Блок шема модула PC(Program

Counter)

Блок шема меморије није прегледна

због величине саме меморије.

Опис појединих модула биће изложен

у наставку.

4. ИМПЛЕМЕНТАЦИЈА

4.1. Увод

Имплементација је извршена

кориштењем Quartus II програмског пакета.

Дизајн је подијељен на двије цјелине:

1. Управљачка јединица реализована као

машина стања

2. Остали модули који учествују у

размјени податакa (dataflow)

4.2. Реализација

Најважнији дио система представља

машина стања која је уједно и генератор

управљачких сигнала. Машина стања је

Милијева машина јер наредно стање

регистра стања машине зависи од тренутних

вриједности улазних сигнала. Машина има

30 стања. Дијаграм стања изгледа овако:

Сл. 9 FSM Chart

Page 6: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 6 -

Са слике 9 уочљив је ток промјене

стања. Почетно стање је s0 (крајње лијево).

Треће стање слијева (s23) је формално

посљедње стање машине у случају да се није

десио прекид.

Наиме, концепт машине стања се

показао подесним за моделовање

управљачке јединице µP, јер се процес

извршавања инструкције у свим

микропроцесорима састоји из неколико

консекутивних операција:

1. Прибављање инструкције (fetch)

2. Прибављање операнада

3. Декодовање инструкције (decode)

4. Извршавање (execution)

5. Упис резултата (write-back)

Тако је урађено и овдје; поједине

групе стања представљају поменуте фазе,

при чему се у сваком стању генеришу

одговарајући управљачки сигнали.

У прилогу 1 се налази фајл cpu_defs у

коме су дефинисане генеричке константе,

инструкције и неки специјални сигнали, што

омогућава једноставну модификацију

система. На примјер, могуће је мијењати

ширину магистрале (word_w), ширину

операционог кода(op_w)(самим тим и број

инструкција) и мнемонике самих

инструкција. Из прилога се види да је

реализован систем са 12 битном магистралом

при чему је адреса дужине 8 бита, а

операциони код 4 бита. Дефинисано је 10 од

могућих 16 инструкција

(store,outper,load,inc,dec,jmp,push,pop,set_dio

de,reti,jnz,neg).

Све инструкције раде са једним

операндом, тако да се сви преноси података

врше посредством акумулатора (acc).

Значење појединих мнемоника:

1. Store (упис из акумулатора у

спецификовану меморијску локацију)

store adresa_mem_lokacije

2. Outper (упис из акумулатора у

периферну локацију)

outper adresa_perif_lokacije 3. Load (читање из меморије, садржај се

смјешта у акумулатор)

load adresa_mem_lokacije 4. inc,dec

(инкрементовање, декрементовање

садржаја акумулатора)

inc (нема аргумента, али се мора

поставити адреса због формата

инструкционе ријечи)

5. jmp (безусловни скок на адресу

спецификовану инструкцијом)

jmp adresa_mem_lokacije 6. push,pop (рад са стеком)

7. set_diode (укључивање диоде)

8. reti (повратак из програма за обраду

прекида)-Retire from Interrupt

9. jnz (скок под условом да није

постављен zero flag )-jump if not zero

на адресу спецификовану

инструкцијом

jnz adresa_mem_lokacije 10. neg (форма првог комплемента

садржаја акумулатора)

У прилогу 2 дат је фајл sequencer.vhdl

у коме је описана управљачка јединица

микропроцесора. Идеја реализације

машином стања захтијева да сви интерни

управљачки сигнали буду активни само за

вријеме трајања једног такт циклуса.

Наиме, сигнали који су генерисани у

току датог стања машине, због софтверске

особине сигнала да преузму вриједност тек

након завршетка процеса,а процес је активан

на позитивну ивицу, неће остварити своје

дејство у том циклусу, већ у сљедећем. У

току позитивне ивице наредног такт

импулса, по уласку у процес, а прије ресета,

управљачки сигнали остварују своје дејство.

Сви модули су пројектовани да испитују

вриједности управљачких сигнала на

позитивне ивице такт сигнала. О томе треба

водити рачуна нарочито ако ови сигнали

побуђују уређаје који производе сличне

сигнале (декодери), јер у том случају

процесор се мора довести у стање застоја

(stall) од једног циклуса да би се поменути

сигнали генерисали правовремено.

Као што је раније споменуто, након

извршења сваке инструкције провјера се да

ли је дошло до постављања захтјева за

прекид, у овом случају од једине периферије

(тајмера), након чега се инструкциони

Page 7: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 7 -

циклус понавља. О самом прекидном

механизму биће ријечи касније.

У оквиру прилога 2 коментарисана је

улога појединих стања машине. Скренуо бих

пажњу на стање s3 у коме се врши

декодовање операционог кода инструкције и

стање s23 у коме се врши провјера постојања

захтјева за прекид (погледати коментаре).

Генерисани управљачки сигнали су

улазни сигнали за преостале модуле система,

а то су:

1. Arithmetic-Logic Unit (ALU)

2. Instruction Pointer (IP)

3. Program Counter (PC)

4. Stack Pointer (SP)

5. Timer

6. Decoder

7. RAM

Улазни сигнали за управљачку

јединицу су ,поред неопходног такта и

ресета ,још и zero flag, opcode и tmr_intr.

Прекидни систем овог система је

крајње једноставан и ослања се на механизам

опслуживања прекида сличан µР 8086.

Наиме, када тајмер генерише захтјев за

прекид, он бива уочен у стању ѕ23, а потом

слиједи секвенца операција:

1. Припрема стека за пријем тренутног

садржаја програмског бројача

2. Постављање садржаја програмског

бројача на стек

3. Генерисање сигнала interrupt

acknowledge и очитавање типа

прекида

4. Брисање interrupt flag-a

5. Упис типа у програмски бројач и скок

на почетак ISR (Interrupt Service

Routine)

6. На крају рутине мора стајати

инструкција reti за повратак

програма на мјесто гдје је био

прекинут

Овај систем има двије могућности

сигнализације спољњем свијету, путем диоде

или излазног порта. У ту сврху је

дефинисана и инструкција set_diode која по

укључивању диоде задржава микропроцесор

у том стању (корисна при тестирању

система). Излазном порту се приступа

инструкцијама за комуникацију са

периферијама.

Пренос података кроз систем обавља

се преко 1 магистрале (12 битне) тако да је

потребно мултиплексирати у времену

сигнале података и адреса. Магистрала је

дефинисана као улазно-излазни сигнал

sysbus који повезује управљачку јединицу са

остатком система који је реализован у виду

модула.

У прилогу 3 дат је VHDL фајл

PC.vhdl који представља реализацију

програмског бројача.

Програмски бројач је реализован као

секвенцијална мрежа чије се стање на

почетку сваког инструкционог циклуса

инкрементује,упућујући на наредну

инструкцију у програму, изузев уколико је у

питању инструкција скока када долази до

директног уписа у програмски бројач адресе

која је садржана у самој инструкцији скока.

По ресету система, програмски бројач креће

од адресе 0.

Важно је напоменути да се приликом

очитивања програмског бројача користи тзв.

маска за адресу која представља 4 водеће 0

које одговарају инструкционом коду (rfill).

Осврћући се на претходну описану

машину стања програмски бројач се

инкрементује у стању ѕ0, а директно уписује

садржајем меморијског регистра (MDR) у

случају гранања у програму (стање ѕ3).

У прилогу 4 дат је VHDL фајл IR.vhdl

који представља реализацију инструкционог

регистра. Овај регистар има 2 основне

функције:

1. Екстракција операционог кода

2. Екстракција адресе

Ове фунцкије су реализоване на

почетку архитектуре ентитета и реализују се

асинхроно тј. независно од системског такта.

Екстраховани операциони код и адреса су

излазни сигнали модула, и користи их

контролна јединица (машина стања) тако

што адресу операнда одмах смијешта у

адресни регистар (MAR-Memory Address

Register), а операциони код за одређивање

сљедећег стања.

Page 8: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 8 -

Контролни сигнали који иницирају

ове операције генеришу се током стања ѕ3

након прибављања саме инструкције.

У прилогу 5 дат је VHDL фајл SP.vhdl

који представља реализацију stack pointer-а.

Стек је неопходан системима који

подржавају рад са процедурама и прекидима.

Наиме, стек представља резервисани дио

радне меморије који је реализован као LIFO

структура (Last In First Out). На стек се

постављају параметри који се просљеђују

приликом позива процедуре или се користи

за чување повратне адресе приликом уласка

у прекидну рутину.

Овај систем користи стек из другог

горе наведеног разлога. Ѕtack pointer упућује

на врх стека, и приликом постављања

податка на стек он се инкрементује (разлика

у односу на конвенционалне системе), а

приликом „скидања“ податка са стека

декрементује. У овом систему стек заузима

задње 32 локације у меморији (12 битне, по

потреби може се проширити).

За комуникацију са стеком на

располагању су двије инструкције push и pop

које постављају односно скидају 1 12-битни

податак са стека, респективно. Приликом

уласка у обраду прекида постављање

програмског бројача на стек се обавља

аутоматски, али је неопходно инструкцијом

reti назначити крај рутине за обраду прекида,

када се садржај програмског бројача уписује

са стека.

Приликом рада са стеком треба бити

опрезан и све што се постави на стек мора се

са истог и уклонити.

Генерисање неопходних управљачких

сигнала (inc_sp,dec_sp,sp_bus)одиграва се у

стањима ѕ14-ѕ22. Треба напоменути да се

приликом комуникације са стеком користи

акумулатор.

Горе поменуто аутоматско

постављање садржаја програмског бројача на

стек се обавља у стањима ѕ23, ѕ26-ѕ30.

У прилогу 6 дат је VHDL фајл

status_port.vhdl који представља реализацију

излазног 4-битног порта (једина ф-ја овог

порта у конкретном систему је сигнализација

проласка временског интервала од 1ѕ, његова

величина, намјена и сл. се на једноставан

начин могу модификовати и прилагодити

другим захтјевима).

За упис садржаја на овај порт

неопходно је да декодер адресе генерише

неопходни сигнал (који је својствен само тој

периферији)на основу његове адресе (која је

2h (0000 0000 0010b) и да машина стања

генерише општи сигнал за селектовање

периферије (tmr_sel1). Пројектовани систем

има могућност адресирања 4k периферних

локација2.

У прилогу 7 дат је VHDL фајл

dec.vhdl који представља реализацију

адресног декодера. Адресни декодер се

активира управљачким сигналом m_io (који

се користи за временско мултиплексирање

приступа меморији и улазно-излазном

подсистему). Захваљујући њему меморија и

У/И подсистем су раздвојени (уштеда

меморијског простора), али су зато

неопходне инструкције за приступ У/И

подсистему (у овом систему то је

инструкција outper).

У прилогу 8 дат је VHDL фајл

timer.vhdl који представља реализацију

тајмера. У питању је 12-битни тајмер са

интерним прескалером, програмабилном

брзином бројања и управљачким регистром.

Тајмер посједује 2 регистра:

1. Бројачки регистар (port1)

2. Контролни регистар (port2)

x x x x x PS1 PS0 CE

Дијаграм 1. Контролни регистар

CE-Count Enable омогућење бројања

PS0- Pre Scaler0

PS1- Pre Scaler1 –бити који одређују брзину

бројања

По добројавању до 0 тајмер генерише

сигнал прекида tmr_intr и поставља тзв. тип

1 Назив сигнала је можда неадекватан, али је

посљедица надоградње система у чијој је првобитној

верзији једина периферија био тајмер. 2 Локације 0h,1h су резервисане за тајмер.

Page 9: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 9 -

прекида (адресу на коју се треба

позиционирати приликом прекида). Сигнал

tmr_intr се мора ресетовати од стране

машине стања сигналом clrf (clear flag) што

се извршава у стању ѕ29.

Тајмер има интерни прескалер са 5 из

разлога што већина инструкција

микропроцесора траје 5 такт циклуса, што

утиче на могућност прецизног одређивања

протеклог времена. Наиме, протекло вријеме

се рачуна на основу броја прекида тајмера и,

обзиром да одбројавање креће послије

иницијализације, не би било коректно да се

прекид јави усред извршавања инструкције

јер би се јавила непрецизност усљед

изгубљених такт интервала.

Напоменуто је да „скоро“ све

инструкције трају 5 такт циклуса. Наиме,

постоје само 2 инструкције које трају дуже

(push, pop), али непрецизност усљед

извршавања ових инструкција је занемарива

због њихове ријеткости. Најважнија

инструкција (jmp),којом се чека у

бесконачној петљи на прекид тајмера,

извршава се тачно у интервалу од 5 такт

циклуса.

У самом VHDL фајлу тајмера у

коментарима је приказана могућност

промјене брзине бројања, која се контролише

битима са тежином 1 и 2 контролног

регистра.

У прилогу 9 дат је VHDL фајл

ram2.vhdl који представља реализацију RAM

меморије. Капацитет меморије је 256х12

бита. Модул садржи два регистра (бафера)

MDR и MAR који служе за привремено

чување података и адреса, респективно.

Редни број меморијске локације је дат

у децималном облику.

У прилогу је дат садржај меморије са

програмом и прекидном рутином који би

обављао сљедеће:

1. Иницијализација тајмера

2. „Чекање“ на прекид

3. У случају прекида скок на прекидну

рутину

4. У прекидној рутини се врши

декрементовање варијабле и провјера

да ли се дошло до 0.

5. У случају да се дошло до 0 варијабла

добија иницијалну вриједност, тајмер

се поново иницијализује да броји

испочетка и стање статусног порта се

комплементира

У прилогу 10 дат је VHDL фајл

ram.vhdl који такође представља реализацију

RAM меморије,тачније интерфејса са

интерном меморијом FPGA чипа. Недостатак

оваквог приступа је то што се садржај

меморије мора ручно уписати у интерну

меморију чипа посредством интерфејса за

рад са чипом.

У прилогу 11 дат је VHDL фајл

sistem.vhdl који представља реализацију

комплетног система. У овом фајлу je

извршено повезивање свих модула система

међусобно и са машином стања, посредством

управљачких и других сигнала.

У прилогу 12 дат је распоред

додијељених пинова.

4.2. Резултати симулације

На слици 10 дати су резултати

симулације. За потребе симулације смањен је

интервал времена потребан за

комплементивање статусног порта(да би се

та промјена верификовала). Кориштен je

Waveform Editor .

Јасно је да је симулација успјешна

верификација рада система. У првом реду

дато је стање бројачког регистра, а у другом

стање статусног регистра, који се након

одређеног броја прекида тајмера

комплементира. У четвртом реду су сигнали

који се јављају на системској магистрали.

На слици 11 се налазе исти резултати,

само увећани .

На слици 12 дати су резултати

симулације добијени софтвером Model Sim, а

приказани су таласни облици свих

управљачких сигнала за вријеме извршавања

инструкције outper којом се иницијализује

стање бројачког регистра(у конкретном

случају то је 0.

На слици 13 дати су временски

облици у тренутку генерисања захтјева за

прекид.

Page 10: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 10 -

Сл. 10 Резултати симулације

Сл. 11 Резултати симулације (један циклус одбројавања тајмера)

Сл. 12 Резултати симулације

Page 11: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 11 -

Сл. 12 Резултати симулације (обратити пажњу на сигн. tmr_int,clrf,intr_ack,inc_sp,dec_sp)

5. РЕВИЗИЈЕ И КОМЕНТАРИ

Током израде пројектног задатка извршене

су 2 ревизије и то:

1. Проширење система модулом

програмабилног тајмера

2. Проширење система модулом стека и

прекидним механизмом

Предметни асистент је консултован

по питању реализације механизма обраде

прекида као и приликом провјере

функционалности система.

6. ЛИТЕРАТУРА

[1] Zwolinski, Mark Digital systems design

using VHDL, CMP Books, New York,

USA, 1997.

[2] Armstrong J. R. and F. G. Gray, VHDL

Design Representation and Synthesis,

Englewood Cliffs, NJ:Prentice Hall, 2nd

Edition, 2000.

Page 12: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 12 -

7. ПРИЛОЗИ

Прилог 1

cpu_defs.vhdl

library ieee;

use ieee.std_logic_1164.all;

package cpu_defs is

type opcode is(store,outper,load,inc,dec,jmp,push,pop,set_diode,reti,jnz,neg);

constant word_w:natural:=12;

--sirina magistrale

constant op_w:natural:=4;

--duzina operacionog koda instrukcije

constant rfill:std_logic_vector(op_w-1 downto 0):=(others=>'0'); --maska za adresu

function slv2op(slv: in std_logic_vector)return opcode; --f-ja za konverziju std_logic_vector(slv)

-- u opcode(enumeracija)

function op2slv(op:in opcode)return std_logic_vector; --f-ja za obrnutu konverziju

end package cpu_defs;

package body cpu_defs is

type optable is array(opcode) of std_logic_vector(op_w-1 downto 0);

constant trans_table:optable:=("0000","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011");

--operacioni kodovi instrukcija

function op2slv(op:in opcode)return std_logic_vector is

begin

return trans_table(op);

end function op2slv;

function slv2op(slv: in std_logic_vector)return opcode is

variable transop:opcode;

begin

for i in opcode loop

if slv=trans_table(i) then

transop:=i;

end if;

end loop;

return transop;

end function slv2op;

end package body cpu_defs;

Page 13: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 13 -

Прилог 2

sequencer.vhdl

library ieee;

use ieee.std_logic_1164.all;

use work.cpu_defs.all;

entity sequencer is

port(clk,reset,tmr_intr,z_flag:in std_logic;

op:in opcode;

ACC_bus,load_ACC,PC_bus,load_PC,load_IR,load_MAR,MDR_bus,load_MDR,ALU_ACC,ALU_add,ALU_sub,INC_PC,

Addr_bus,CS,RD,M_IO,tmr_sel,inc_sp,dec_sp,sp_bus,intr_ack,clrf,ALU_neg,diode_on:out std_logic); --upravljacki signali

end sequencer;

architecture ponasanje of sequencer is

type state is(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10,s11,s12,s13,s14,s15,s16,s17,s18,s19,s20,s21,s22,s23,s24,s25,s26,s27,s28,s29,s30);

signal present_state,next_state:state;

begin

process(clk,reset)

begin

if reset='1' then

present_state<=s0;

elsif(rising_edge(clk)) then

present_state<=next_state;

end if;

end process;

process(present_state,op,z_flag,tmr_intr) is

begin

ACC_bus<='0'; --reset svih upravljackih signala poslije svakog clk

load_ACC<='0';

PC_bus<='0';

load_PC<='0';

load_IR<='0';

load_MAR<='0';

MDR_bus<='0';

load_MDR<='0';

ALU_ACC<='0';

ALU_add<='0';

ALU_sub<='0';

INC_PC<='0';

Addr_bus<='0';

CS<='0';

RD<='0';

M_IO<='0';

tmr_sel<='0';

inc_sp<='0';

dec_sp<='0';

sp_bus<='0';

intr_ack<='0';

clrf<='0';

ALU_neg<='0';

Page 14: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 14 -

case present_state is

when s0=> --inkrementovanje programskog brojaca

PC_bus<='1';

load_MAR<='1';

INC_PC<='1';

load_PC<='1';

next_state<=s1;

when s1=> --ocitavanje instrukcije

CS<='1'; --CS (chip select) za omogucenje RAM-a

RD<='1'; --RD=1 ocitavanje, RD=0 upis u RAM

next_state<=s2;

when s2=>

MDR_bus<='1';

load_IR<='1'; --punjenje Instruction Register-a

next_state<=s3;

when s3=>

addr_bus<='1'; --ekstrakcija adrese iz IR

load_mar<='1'; -- adresa je spremljena u MAR(Memory Address Register)

if op=store then --dekodovanje instrukcionog opkoda

next_state<=s4;

elsif op=outper then

m_io<='1'; --pristup U/I podsistemu, a ne memoriji (signalizacija U/I dekoderu)

next_state<=s6;

elsif op=set_diode then

next_state<=s12;

elsif op=push then

next_state<=s14;

elsif op=pop then

next_state<=s17;

elsif op=reti then

next_state<=s20;

elsif op=jmp then

load_PC<='1'; --naredba skoka zahtijeva postavljanje

-- sadrzaja programskog brojaca na odgovarajucu adresu programa

next_state<=s23;

elsif op=jnz then

if z_flag='0' then

load_PC<='1'; --jump if not zero (grananje programa u slucaju da zero fleg nije postavljen)

next_state<=s23;

else

next_state<=s11;

end if;

else next_state<=s7;

end if;

--**instrukcija store**

when s4=> --store instrukcija mem<=acc

ACC_bus<='1';

load_MDR<='1';

next_state<=s5;

when s5=>

CS<='1';

RD<='0';

next_state<=s23; --s23 je zadnji ciklus svake instrukcije, ujedno provjera da li postoji prekid

--**instrukcija outper**

when s6=> --potreban 1 ciklus za stabilizaciju izlaznih signala dekodera

next_state<=s13;

when s13=> --nakon selektovanja odgovarajuce periferije, vrsi se upis

ACC_bus<='1';

Page 15: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 15 -

tmr_sel<='1'; --omogucenje periferije

next_state<=s23;

--**instrukcija set_diode*

when s12=>

diode_on<='1';

next_state<=s12;

--**instrukcija push**

when s14=>

inc_sp<='1'; --inkrementovanje stack pointer-a

next_state<=s15;

when s15=>

sp_bus<='1'; --postavaljanje adrese vrha steka u MAR

load_mar<='1';

next_state<=s16;

when s16=>

acc_bus<='1'; --sadrzaj akumulatora se postavlja u MDR (Memory Data Register)

load_mdr<='1';

next_state<=s25;

when s25=> --upis na stek koji je realizovan kao rezervisani dio RAM memorije

cs<='1';

rd<='0';

next_state<=s23;

--**instrukcija pop**

when s17=> --pop-> proces smjestanja vrha steka u MAR

sp_bus<='1';

load_mar<='1';

dec_sp<='1'; --dekrementovanje vrha steka

next_state<=s18;

when s18=> --ocitavanje vrha steka

cs<='1';

rd<='1';

next_state<=s19;

when s19=>

mdr_bus<='1';

load_acc<='1'; --sadrzaj vrha steka se smjesta u akumulator

next_state<=s23;

--**instrukcija reti (Retire from interrupt)**

when s20=>

sp_bus<='1'; --proces smjestanja vrha steka u MAR

load_mar<='1';

dec_sp<='1';

next_state<=s21;

when s21=> --ocitavanje vrha steka

cs<='1';

rd<='1';

next_state<=s22;

when s22=> --restauracija programskog brojaca

mdr_bus<='1';

load_pc<='1';

next_state<=s23;

when s7=>

CS<='1'; --mdr je pun; ocitan je podatak jer ce biti potreban

RD<='1';

if op=load then

next_state<=s8;

else

next_state<=s9; --onda je aritmeticka operacija nad podacima

Page 16: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 16 -

end if;

--**instrukcija load**

when s8=>

MDR_bus<='1';

load_ACC<='1'; --acc<=memory

next_state<=s23;

--**aritmeticke instrukcije**

when s9=>

ALU_ACC<='1';

load_ACC<='1';

if op=inc then

ALU_add<='1';

elsif op=dec then

ALU_sub<='1';

elsif op=neg then

ALU_neg<='1';

end if;

next_state<=s23;

when s11=>

next_state<=s23;

--**provjera postojanja zahtjeva za prekid**

when s23=>

if tmr_intr='1' then

inc_sp<='1'; --priprema steka

next_state<=s26;

else

next_state<=s0;

end if;

when s26=>

PC_bus<='1';

load_MDR<='1'; --upis sadrzaja programskog brojaca u MDR

next_state<=s27;

when s27=>

sp_bus<='1';

load_MAR<='1'; --upis adrese vrha steka u MAR

next_state<=s28;

when s28=>

cs<='1';

rd<='0'; --upis u RAM

next_state<=s29;

when s29=>

intr_ack<='1'; --zahtjev za postavljanjem tipa prekida

load_PC<='1'; --nova vrijednost programskog brojaca,skok na ISR (Interrupt Service Routine)

clrf<='1'; --brisanje flega (tj. postavljenog zahtjeva za prekidom)

next_state<=s30;

when s30=> --dodatno stanje zbog upisa u PC

next_state<=s0;

Page 17: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 17 -

Прилог 3

ALU.vhdl

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.cpu_defs.all;

entity PC is

port(clk,reset:in std_logic;

PC_bus,load_PC,INC_PC:in std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0));

end PC;

architecture ponasanje of PC is

signal count:unsigned(word_w-op_w-1 downto 0):=(others=>'0');

begin

sysbus<=rfill&std_logic_vector(count) when PC_bus='1' else (others=>'Z');

--postavljanje sadrzaja programskog brojaca na magistralu

process(clk,reset)

begin

if reset='1' then

count<=(others=>'0');

elsif rising_edge(clk) then

if load_PC='1' then

if inc_pc='1' then

count<=count+1; --inkrementovanje programskog brojaca

else

count<=unsigned(sysbus(word_w-op_w-1 downto 0)); --u slucaju

--grananja

--direktan upis u

--programski brojac

end if;

end if;

end if;

end process;

end ponasanje;

Page 18: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 18 -

Прилог 4

IR.vhdl

library ieee;

use ieee.std_logic_1164.all;

use work.cpu_defs.all;

entity IR is

port(clk,reset:in std_logic;

addr_bus,load_ir:in std_logic;

op:out opcode;

sysbus:inout std_logic_vector(word_w-1 downto 0));

end IR;

architecture ponasanje of IR is

signal instr_reg:std_logic_vector(word_w-1 downto 0);

begin

sysbus<=rfill&instr_reg(word_w-1-op_w downto 0) when addr_bus='1' else (others=>'Z');

--ekstrakcija adrese iz instrukcije

op<=slv2op(instr_reg(word_w-1 downto word_w-op_w));

- --ekstrakcija operacionog koda iz adrese

process(clk,reset)

begin

if reset='1' then

instr_reg<=(others=>'0');

elsif rising_edge(clk) then

if load_ir='1' then

instr_reg<=sysbus;

end if;

end if;

end process;

end ponasanje;

Page 19: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 19 -

Прилог 5

SP.vhdl

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.cpu_defs.all;

entity SP is

port(clk,reset:in std_logic;

SP_bus,INC_SP,DEC_SP:in std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0));

end SP;

architecture ponasanje of SP is

signal pointer:unsigned(word_w-op_w-1 downto 0):="11100000";

--pocetak steka 32B na kraju memorijskog prostora

begin

sysbus<=rfill&std_logic_vector(pointer) when SP_bus='1' else (others=>'Z');

--ocitavanje stack pointer-a

process(clk,reset)

begin

if reset='1' then

pointer<="11100000"; --inicijalizacija

elsif rising_edge(clk) then

if inc_sp='1' then

pointer<=pointer+1;

--SP=SP+1

elsif dec_sp='1' then

--SP=SP-1

pointer<=pointer-1;

end if;

end if;

end process;

end ponasanje;

Page 20: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 20 -

Прилог 6

Status_port.vhdl

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.cpu_defs.all;

entity status_port is

port(clk,reset:in std_logic;

load_status,tmr_sel: in std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0);

izlaz:out std_logic_vector(3 downto 0));

end status_port;

architecture ponasanje of status_port is

begin

process(clk,reset)

variable data:std_logic_vector(3 downto 0):="0000";

begin

if reset='1' then

data:="0000";

elsif rising_edge(clk) then

if load_status='1' and tmr_sel='1' then

data:=sysbus(3 downto 0);

end if;

izlaz<=data;

end if;

end process;

end ponasanje;

Page 21: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 21 -

Прилог 7

dec.vhdl

library ieee;

use ieee.std_logic_1164.all;

use work.cpu_defs.all;

entity dec is

port(sysbus:inout std_logic_vector(word_w-1 downto 0);

clk,reset,m_io:in std_logic;

load_port1,load_port2,load_status:out std_logic:='0');

end dec_1_2;

architecture ponasanje of dec is

signal data:std_logic_vector(word_w-op_w-1 downto 0):=(others=>'1');

begin

process(clk,reset)

begin

if reset='1' then

data<=(others=>'1');

load_port1<='0';

load_port2<='0';

load_status<='0';

elsif rising_edge(clk) then

if m_io='1' then

data<=sysbus(word_w-op_w-1 downto 0);

else

case data is --dekodovanje ulaznih adresnih signala (u ovom sistemu iskoristena su samo 3 porta)

when "00000000"=>

load_port1<='1';

load_port2<='0';

load_status<='0';

when "00000001"=>

load_port1<='0';

load_port2<='1';

load_status<='0';

when "00000010"=>

load_port1<='0';

load_port2<='0';

load_status<='1';

when others=>

load_port1<='0';

load_port2<='0';

load_status<='0';

end case;

end if;

end if;

end process;

end ponasanje;

Page 22: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 22 -

Прилог 8

timer.vhdl

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.cpu_defs.all;

entity timer is

port(clk,reset,load_port1,load_port2,tmr_sel,intr_ack,clrf:in std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0);

tmr_intr:out std_logic:='0';

--izlaz:out std_logic_vector(7 downto 0):="00000000"); izlaz je opcion

end timer;

architecture ponasanje of timer is

constant zero:unsigned(word_w-1 downto 0):=(others=>'0');

signal dopustenje:std_logic:='0';

begin

sysbus<=rfill&"00001001" when intr_ack='1' else (others=>'Z'); --tip prekida tajmera(ujedno i adresa pocetka ISR)

process(clk,reset)

variable data:unsigned(word_w-1 downto 0);

variable var:integer:=0;

begin

if reset='1' then

tmr_intr<='0';

var:=0;

elsif rising_edge(clk) then

if clrf='1' then

tmr_intr<='0';

--brisanje zahtjeva za prekidom

end if;

if load_port1='1' and tmr_sel='1' then

data:=unsigned(sysbus(word_w-1 downto 0)); --upis u brojac

elsif load_port2='1' and tmr_sel='1' then

if sysbus(0)='1' then

dopustenje<='1';

--startovanje brojaca

end if;

--case sysbus(2 downto 1) is --napomena: opcioni sadrzaj

--moguce opcije za skaliranje ulaznog takta

-- when "00"=>

-- data3<=27000000; --1 Hz

-- when "01"=>

-- data3<=13500000; --2 Hz

-- when "10"=>

-- data3<=5400000; --5 Hz

-- when "11"=>

-- data3<=2700000; --10 Hz

-- when others=>

-- data3<=27000000;

Page 23: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 23 -

-- end case;

end if;

--izlaz<=std_logic_vector(data(7 downto 0)); opciono ako je potrebno pratiti stanje brojackog registra

if dopustenje='1' then

var:=var+1;

if var=5 then

--interni preskaler sa 5

data:=data-1;

if data=zero then

tmr_intr<='1'; --generisanje zahtjeva za prekid

dopustenje<='0'; --zaustavljanje tajmera

end if;

var:=0;

end if;

end if;

end if;

end process;

end ponasanje;

Page 24: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 24 -

Прилог 9

RAM2.vhdl

library ieee;

use ieee.std_logic_1164.all;

use ieee.numeric_std.all;

use work.cpu_defs.all;

entity RAM2 is

port( clk,reset:in std_logic;

mdr_bus,load_mdr,load_mar,cs,r:in std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0));

end RAM2;

architecture ponasanje of RAM2 is

signal mdr:std_logic_vector(word_w-1 downto 0); --MDR registar

signal mar:unsigned(word_w-op_w-1 downto 0); --MAR registar

begin

sysbus<=mdr when mdr_bus='1' else (others=>'Z');

process(clk,reset) is

type mem_array is array(0 to 2**(word_w-op_w)-1) --memorijski prostor od 2^8=256 B

of std_logic_vector(word_w-1 downto 0);

variable mem:mem_array;

constant prog:mem_array:=(

--************GLAVNI PROGRAM*************

0=>op2slv(load)&"00000101", --upis u akumulator sa adrese 5

1=>op2slv(outper)&"00000000", --upis u brojacki register tajmera

2=>op2slv(load)&"00000110", --upis u akumulator sa adrese 6

3=>op2slv(outper)&"00000001", --upis u kontrolni registar tajmera

4=>op2slv(jmp)&"00000100", --zadrzavanje programa

--varijable

5=>"111111111111", --var1=4095

6=>"000000000001", --var2 omogucenje tajmera(ctrl word)

7=>"010100100110", --var3=1318 jer je 1318*4095*5~27000000

8=>"010100100110", --var4=var3

9=>op2slv(jmp)&"00110000", --adresa skoka za ISR tajmera (48d)

10=>"111111111111",

--*************pocetak ISR***************** --sustina ISR je

--dekrementovanje kontrolne

--varijable za mjerenje perioda

--vremena od 1s

--nakon cega slijedi reload

--tajmera i komplementiranje sadrzaja

--izlaznog registra

Page 25: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 25 -

48=>op2slv(load)&"00000111", --var3

49=>op2slv(dec)&"00000000", --dekrementovanje

50=>op2slv(store)&"00000111", --store var3

51=>op2slv(jnz)&"00111010", --skok na 58d ako nije prosla 1s

52=>op2slv(load)&"10000000", --sa adrese 128d

53=>op2slv(neg)&"00000000", --komplementiranje

54=>op2slv(store)&"10000000", --store

55=>op2slv(outper)&"00000010", --slanje na port 2

56=>op2slv(load)&"00001000", --var3<=var4

57=>op2slv(store)&"00000111",

58=>op2slv(load)&"00000101", --reload tajmera

59=>op2slv(outper)&"00000000",

60=>op2slv(load)&"00000110", --omogucenje tajmera

61=>op2slv(outper)&"00000001",

62=>op2slv(reti)&"00000000",

--*******kraj ISR************

128=>"000000000000",

others=>(others=>'0'));

begin

if reset='1' then

mdr<=(others=>'0');

mar<=(others=>'0');

mem:=prog;

elsif rising_edge(clk) then

if load_mar='1' then

mar<=unsigned(sysbus(word_w-op_w-1 downto 0)); --punjenje MDR registra

elsif load_mdr='1' then

mdr<=sysbus; --punjenje MAR registra

elsif cs='1' then

if r='1' then

mdr<=mem(to_integer(mar)); --ocitavanje memorije

else mem(to_integer(mar)):=mdr; --upis u memoriju

end if;

end if;

end if;

end process;

end ponasanje;

Page 26: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 26 -

Прилог 10

ram.vhdl

Прилог 11

library ieee;

use ieee.std_logic_1164.all;

use work.cpu_defs.all;

entity RAM is

port(clk,reset,MDR_bus,load_MDR,load_MAR,CS,WR,RD:in std_logic;

cs1,wr1,rd1:out std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0);

selektor:out std_logic_vector(17 downto 0):="000000000000000000";

upis:inout std_logic_vector(word_w-1 downto 0));

end RAM;

architecture ponasanje of RAM is

signal mdr:std_logic_vector(word_w-1 downto 0);

begin

cs1<=cs;

wr1<=wr;

rd1<=rd;

sysbus<=mdr when mdr_bus='1' else (others=>'Z');

process(clk,reset)

begin

if reset='1' then

mdr<=(others=>'0');

elsif rising_edge(clk) then

if load_MAR='1' then

selektor(word_w-op_w-1 downto 0)<=sysbus(word_w-op_w-1 downto 0);

elsif load_MDR='1' then

mdr<=sysbus;

upis<=sysbus;

elsif cs='1' then

if WR='0' then

mdr<=upis;

end if;

end if;

end if;

end process;

end ponasanje;

Page 27: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 27 -

sistem.vhdl

library ieee;

use ieee.std_logic_1164.all;

use work.cpu_defs.all;

entity sistem is

port(clk,reset:in std_logic;

sysbus:inout std_logic_vector(word_w-1 downto 0):=(others=>'0');

dioda:out std_logic;

izlaz:out std_logic_vector(3 downto 0));

end sistem;

architecture ponasanje of sistem is

signal ACC_bus,load_ACC,PC_bus,load_PC,load_IR,load_MAR,MDR_bus,load_MDR,ALU_ACC,ALU_add,ALU_sub,INC_PC,

Addr_bus,CS,RD,M_IO,load_port1,load_port2,tmr_intr,tmr_sel,inc_sp,dec_sp,sp_bus,intr_ack,clrf,z_flag,ALU_neg,load_st

atus:std_logic;

signal tmp1,tmp2:std_logic_vector(3 downto 0);

signal op:opcode;

begin

u1: entity work.sequencer port

map(clk,reset,tmr_intr,z_flag,op,ACC_bus,load_ACC,PC_bus,load_PC,load_IR,load_MAR,MDR_bus,load_MDR,ALU_ACC,A

LU_add,ALU_sub,INC_PC,

Addr_bus,CS,RD,M_IO,tmr_sel,inc_sp,dec_sp,sp_bus,intr_ack,clrf,ALU_neg,diode_on);

u2: entity work.IR port map(clk,reset,addr_bus,load_ir,op,sysbus);

u3: entity work.PC port map(clk,reset,PC_bus,load_PC,INC_PC,sysbus);

u4: entity work.ALU port map(clk,reset,ACC_bus,load_ACC,ALU_ACC,ALU_add,ALU_sub,ALU_neg,sysbus,z_flag);

--u5: entity work.RAM port map(izlaz,reset,MDR_bus,load_MDR,load_MAR,CS,WR,RD,cs1,wr1,rd1,sysbus,mar,upis);

u6: entity work.dec_1_2 port map(sysbus,clk,reset,M_IO,load_port1,load_port2,load_status);

u7: entity work.timer port map(clk,reset,load_port1,load_port2,tmr_sel,intr_ack,clrf,sysbus,tmr_intr);

u8: entity work.RAM2 port map(clk,reset,mdr_bus,load_mdr,load_mar,cs,rd,sysbus);

u9: entity work.SP port map(clk,reset,SP_bus,INC_SP,DEC_SP,sysbus);

u10:entity work.status_port port map(clk,reset,load_status,tmr_sel,sysbus,izlaz);

end ponasanje;

Page 28: Izvjestaj_projektni

Пројектовање дигиталних система – Пројектни задатак

- 28 -

Прилог 12

Распоред додијељених пинова