Ми хардуерът принципно се дели на две групи:
1)
Комбинаторна логика - това са ти всички логически, математиматически и каквито се сетиш функции при които резултатът зависи пряко от входа на функцията. Примерно прост суматор - подаваш му на входовете 2 и 2 а на изхода получаваш 4, щото 2+2 е приблизително 4
2)
Логика с памет - това е хардуер, който има някаква памет и тая памет описва някакво вътрешно състояние. Изходите на такъв хардуер могат да зависят както от входовете, така и от вътрешното състояние.
Може би се чудиш защо е толкова важно да се прави разлика между горните две... Има много причини, най-малко теорията на тия две групи е различна. При комбинаторната логика всичко се свежда до булева алгебра и независимо какво си написал, в крайна сметка може да се сведе до схема с И-НЕ елементи. Демек нямаш никакви грижи с компилатора - той винаги оптимизира комбинаторната логика до възможно най-добрия резултат. (За разлика от С-компилаторите, които не винаги се усещат).
Теорията зад паметите е малко по-разлияна, там са едни автомати, Тюринги ала-бала но това теб не те касае много. Важно е само да знаеш че има разлика между комбинаторна логика и логика с памет.
Комбинаторната логика по дефиниция си е асинхронна, т.е. няма нещо специално по което да се "синхронизира". Даваш нещо на входа получаваш резултат на изхода.
По принцип логиката с памет може да бъде синхронна и асинхронна, но като за начало забрави за асинхронните памети. И винаги когато чуеш памет си представяй синхронна логика, а след като напреднеш ще говорим и за асинхронни логики с памет.
Всъщност какво и е "синхронното" на една логика и защо се синхронизира?
Представи си 8 битов процесор и 128-битова променлива. Ако работиш в един таск нямаш никакъв проблем с това че променливата и процесора са на различни битове, нали така?
Сега обаче си представи че един таск бъзика променливата примерно я инкрементира, а друг таск или прекъсване я чете. Възниква една лека опасност втория таск да прекъсне първия докато подменя стойностите и да прочете част от старата и част от новата стойност - демек получава се боза...
При хардуера тоя проблем съществува винаги когато имаш променлива с повече от 1 бит, защото два бита трудно се променят едновременно Винаги единия се променя една идея по-бързо и има опасност ти да нацелиш баш тоя момент.
При софтуера тоя проблем се решава със семафорчета или забрана на прекъсването, а при хардуера се решава чрез "синхронна логика", т.е. всички битчета се синхронизират по някакъв сигнал наречен клок и ти си знаеш кога може да ги бараш...
Забележи, че само "логика с памет" може да е наистина синхронна, защото тя трябва да "помни" състоянието си и да не се променя, докато не й разреши съответния клок. Всичката логика която се клати на един и същ клок образува "клок домейн". И в рамките на този домейн сексът е безопасен. Можеш спокойно да си правиш аритметики между променливите, без да се притесняваш колко битови са ти променливите и дали няма да прочетеш грешна стойност. В рамките на един домейн всичко става синхронно и нямаш грижи. Но трябва много да внимаваш когато тръгнеш да ползваш променлива от един домейн в друг. По принцип компилаторите хващат подобни грешки и предупреждават, но общо взето тая грешка съм я виждал и при много добри хардуеристи
Дотук ако си ме разбрал, вече би трябвало да знаеш дали броячът може да се направи с комбинаторна логика или трябва логика с памет. Дали ще е синхронен или не? (не че няма асинхронни но пак казвам това е урок за по-напреднали и не е много нужен).
Ако си наясно с горното вече си готов да "програмираш" хардуер. Остава да научиш как се описва комбинаторна логика и логика с памет в един език за хардуер...
По принцип в VHDL няма изрично указване дали искаш едното или другото. Всичко се свежда до сигнали или вектор от сигнали (многобитови променливи).
Но има два вида оператори, едните sequentional демек които уловно се изпълняват последователно и други които се изпъляват паралелно. Като С програмист си наясно какво значи няколко оператора да се изпълнят последователно. При хардуера обаче цялата последователност се изпълнява за безкрайно малко време да кажем за нулево време. Демек ти може да си го представяш че уж се изпълняват един след друг, но тъй като всеки оператор се изпълнява точно за нула време и общо всичко се изпълнява за нула време "последователност" в буквалния смисъл на думата няма. По-скоро е "приоритет". Но като за С програмист ще ти е по-лесно да си го представяш като последователност и аз така ми е по-лесно
По-интересни са другите оператори - там всичките са независими един от друг и се изпълняват едновременно. Е такова животно няма на С.... Но ще свикнеш, примерно като напишеш:
a <= x+y;
b <= x-y;
Операцоята присвояване е "<=" няма значение кое е първо и кое е второ И двете присвоявания си се изпълняват постоянно във времето и паралелно едно на друго. Последователността в сорс файла няма никакво значение.
Но да се върнем на комбинаторната логика и паметите... И двете могат да се описват с поледователни или паралелни оператори. Комбинаторна логика се получава когато имаш пълно описание.
Примерно:
В случая "а" ти е описано като стойност, която може да определиш ако знаеш sum, x и y. Следователно нямаш нужда от памет...
Докато това:
това изисква памет, понеже "а" се променя само ако sum е активен, а в останалото време трябва да си "помни" стойността. Това е така, защото е "непълно" описана и не може да кажеш колко е "а" ако сум е неактивен.
По принцип логиката с памет се синтезира в процеси... Процесът е все едно някаква функция, която се стартира при промяна на кой да е сигнал от sensitivity list-а (демек параметрите). По принцип съдържа "последователни" оператори, които се изпълняват и процесът заспива отново докато не се получи нова промяна дето да го събуди...
Ето ти го и брояча: