Popularny post rafal2808 Napisano Czerwiec 11, 2019 Popularny post Udostępnij Napisano Czerwiec 11, 2019 Jakiś czas temu na forum zaprezentowałem projekt procesora zrealizowanego na układzie FPGA. Był to układ zrealizowany na dwóch płytkach Elbert v2. Aby go uruchomić należało wykonać dość sporo pracy. Dzisiaj prezentuję pierwszą wersję układu DCE Q816, czyli bezpośredniej kontynuacji poprzedniego projektu. Można powiedzieć, że pierwsza wersja Q818 to tak naprawdę Q816 zrealizowany tylko na jednej płytce Elbert v2. Układ jest w pełni kompatybilny z poprzednim projektem oraz posiada identyczną listę rozkazów. Na ten moment nie będę skupiał się na budowie procesora, ponieważ jest ona praktycznie identyczna jak w układzie Q816. Jedyną różnicą jest to, że pamięć ROM oraz procesor zaimplementowane została na tym samym układzie FPGA. W związku z tym każdy, kto posiada płytkę Elbert v2 może pobrać projekt, który dostępny jest tutaj, a następnie uruchomić procesor Q818 w swoim domu. Po implementacji projektu na płytce FPGA powinniśmy zobaczyć następujący efekt świetlny. Należy również wspomnieć, że porty procesora skonfigurowane zostały w następujący sposób. przełączniki DIP Switch - wejście IN procesora (logika odwrotna) przycisk SW1 - RESET port P1 - wyjście OUT1 procesora diody LED - wyjście OUT2 procesora Programowanie procesora odbywa się poprzez zmianę zawartości pamięci ROM procesora. Aby tego dokonać musimy otworzyć plik ROM.vhd i następnie wpisać binarną zawartość kolejnych komórek pamięci. Najmłodsze 5-bitów to rozkaz dla procesora. Kolejne 8 to tzw. dana bezpośrednia, którą możemy przesłać do innych rejestrów. Poniżej umieszczam spis dostępnych rozkazów procesora oraz instrukcje dla ALU zapisywane w rejestrze C. Na ten moment jest to pierwsza wersja układu Q816 w przyszłości postaram się o uporządkowanie samego kodu, jak i dodanie kolejnych funkcji. O zmianach i kolejnych wersjach postaram się informować w komentarzach do tego posta. 6 Link do komentarza Share on other sites More sharing options...
rafal2808 Czerwiec 15, 2019 Autor tematu Udostępnij Czerwiec 15, 2019 Dostępna jest już kolejna wersja układu wyposażona w pełni funkcjonalny interfejs UART. Poza tym dodane zostały nowe rozkazy dla ALU oraz sam kod procesora został zaktualizowany. Na moim blogu można dowiedzieć się więcej na temat budowy układu oraz pobrać projekt. 2 Link do komentarza Share on other sites More sharing options...
rafal2808 Lipiec 2, 2019 Autor tematu Udostępnij Lipiec 2, 2019 Kolejna wersja procesora jest już gotowa. Tym razem dodana została obsługa rozkazu powrotu. Dzięki temu nie musimy znać dokładnego miejsca, w którym przerwany został program główny. Od teraz procesor przechowuje adres w odpowiednim rejestrze. Więcej na temat mojego projektu można przeczytać tutaj. 2 Link do komentarza Share on other sites More sharing options...
rafal2808 Sierpień 16, 2019 Autor tematu Udostępnij Sierpień 16, 2019 Zapraszam do zapoznania się z zaktualizowaną wersją opisu procesora Q818. Pojawiła się już dość spora sekcja poświęcona architekturze układu oraz blokom tworzącym procesor. 2 Link do komentarza Share on other sites More sharing options...
Polecacz 101 Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Zarejestruj się lub zaloguj, aby ukryć tę reklamę. Produkcja i montaż PCB - wybierz sprawdzone PCBWay! • Darmowe płytki dla studentów i projektów non-profit • Tylko 5$ za 10 prototypów PCB w 24 godziny • Usługa projektowania PCB na zlecenie • Montaż PCB od 30$ + bezpłatna dostawa i szablony • Darmowe narzędzie do podglądu plików Gerber Zobacz również » Film z fabryki PCBWay
Treker (Damian Szymański) Sierpień 19, 2019 Udostępnij Sierpień 19, 2019 @rafal2808 super, że projekt się rozwija 🙂 Jakie dalsze plany? Link do komentarza Share on other sites More sharing options...
rafal2808 Sierpień 19, 2019 Autor tematu Udostępnij Sierpień 19, 2019 @Treker W przyszłości na pewno pojawi się obsługa kolejnych interfejsów takich jak SPI, I2C itd. Dodatkowo planuję też wprowadzenie obsługi wyświetlacza LCD oraz 7-segmentowego. Poważnie też myślę nad dodaniem zewnętrznej pamięci RAM. Można by wówczas zrezygnować z implementowania jej na strukturze FPGA i zwiększyć pojemność pamięci ROM, ale to temat na dalszą przyszłość. Oczywiście cały czas staram się pracować nad projektem i metodą małych kroków zwiększać jego funkcjonalność. 2 Link do komentarza Share on other sites More sharing options...
Popularny post rafal2808 Listopad 26, 2019 Autor tematu Popularny post Udostępnij Listopad 26, 2019 Po dość sporej przerwie wracam do projektu😀, miała ona również swoje plusy, ponieważ udało mi się spojrzeć na całość z nieco innej perspektywy. Wracając do poprzednich wpisów, plany implementacji obsługi kolejnych interfejsów oraz obsługi wyświetlaczy 7 segmentowych zostają. Jednak rezygnuję z wyświetlacza LCD oraz zewnętrznej pamięci RAM. Powodem tego jest początkowe założenie projektu, w czasie jego trwania nieco zapomniane. Cały system ma być ograniczony tylko do płytki Elbert v2. Ewentualne zewnętrzne dodatki nie powinny być wymagane do poprawnego uruchomienia projektu. Jak sama nazwa wskazuje mają to być tylko dodatki. Pojawiła się kolejna wersja projektu DCEQ818 z nieco zoptymalizowanym kodem procesora, dodatkowo sam opis również został zaktualizowany. 3 Link do komentarza Share on other sites More sharing options...
rafal2808 Styczeń 2, 2020 Autor tematu Udostępnij Styczeń 2, 2020 (edytowany) Porządki w projekcie, ciąg dalszy😀 Można powiedzieć że, zaczynam od początku. Projekt zyskał całkowicie nową architekturę, jest to ulepszona wersja pierwotnego pomysłu. Najważniejszym elementem jest dodanie obsługi przerwań zewnętrznych jak i wewnętrznych. Do tej pory żaden realizowany przeze mnie projekt procesora nie posiadał tej funkcji. Sama forma pracy nad projektem również ulegnie pewnej zmianie. Z czasem pojawiać się będą wpisy (facebook+blog+forbot) informujące o zakończeniu etapu projektowania poszczególnych elementów. Dotychczas informowałem raczej o ukończeniu, czy zaktualizowaniu całego projektu, nie jego konkretnych elementów. Dodatkowo nazwa procesora również ulega zmianie od teraz będzie to "Project A". Tak prezentuje się architektura procesora. Każdy z bloków możemy przypisać do jednej z czterech kategorii. Kolorem żółtym zaznaczone zostały wszystkie rejestry, czerwonym bloki pamięci (RAM, ROM), niebieskim multipleksery. Na zielono zaznaczone zostały bloki, które możemy określić jako te najbardziej zaawansowane takie jak ALU, dekoder instrukcji czy kontroler wyświetlaczy 7 segmentowych. Blok kryjący się pod tajemniczą nazwą "LOGIC" jest najprościej mówiąc głównym elementem układu sterowania. To tutaj na podstawie instrukcji, zegara oraz kilku pomniejszych sygnałów określających stan procesora generowane są wszystkie sygnały sterujące dla innych bloków. Najważniejszą z nowości jest dodanie układu przerwań. Na początek obsługiwane będą trzy typy przerwań. Dwa z nich będą aktywowane w momencie wysłania lub odbioru znaku poprzez interfejs UART, trzecim natomiast będzie sygnał zewnętrzny (np. przycisk). Oczywiście dzięki rejestrowi ICR (interrupt control register) możliwe będzie wyłączenie dowolnego z przerwań. Fizycznie projekt zrealizowany zostanie na dobrze już znanej płytce Elbert v2. Oczywiście założenie iż wszystko zrealizowane ma być tylko na tej płytce pozostaje nadal aktualne. Ciąg dalszy nastąpi...😉 Jeśli ktoś zainteresowany jest tym czy innym z moich projektów zapraszam na prowadzoną przeze mnie stronę na facebooku, gdyż to właśnie tam w pierwszej kolejności pojawiają się najnowsze informację. Edytowano Styczeń 2, 2020 przez rafal2808 2 Link do komentarza Share on other sites More sharing options...
marek1707 Styczeń 2, 2020 Udostępnij Styczeń 2, 2020 Ma kilka pytań: Przede wszystkim dziwne jest ścisłe powiązanie (a raczej brak wyraźnego rozgraniczenia) procesora i peryferiów. Mam nadzieję, że nie zrobisz osobnych instrukcji do komunikacji np. z rejestrami UARTa czy LED a będzie to jakoś ujednolicone, np. przez użycie osobnej przestrzeni adresowej banku rejestrów I/O. Z punktu widzenia struktury projektu chyba wygodniej byłoby wydzielić duże bloki właśnie typu procesor, peryferia (UART, LED, ew. kontroler przerwań, może w przyszłości jakieś timery itp) czy pamięć choćby po to, by po sprzęgnięciu je jakimiś dobrze określonymi magistralami można było w łatwy sposób dodawać/usuwać bloki. Obecnie to wygląda na słabo modyfikowalne. Dlaczego aby zapisać coś do B trzeba przepuścić to przez A? Wydaje się to dziwne. Nie możesz przez to używać ALU do innych rzeczy np. inkrementacji/dekrementacji B czy ew. innych przyszłych rejestrów. Czy jest to procesor 4-, 8-, czy 16-bitowy? Jak szeroką przewidujesz pamięć programu (albo jak długi kod operacyjny instrukcji)? Czy będziesz skupiał się na szybkości wykonywania instrukcji (a więc rozbudowie logiki) czy raczej na zajętości FPGA (czyli raczej układ mikroprogramowany)? Wydaje się, że system przerwań powinien być ściśle powiązany z głównym sekwencerem a tego tu nie widać. Czy przyjęte przerwanie będzie jakoś sprzętowo zachowywać kontekst? Bez możliwości zachowania gdziekolwiek choćby PC przerwania trochę nie mają sensu. Jak będzie wyglądać sekwencja porzucenia głównego wątku i rozpoczęcia wykonywania ISR? Czy będą wektory w RAMie? Czy ustalone punkty wejścia? Czy wszystko wchodzi przez jeden adres? Czy będzie stos a jeśli tak to jaki? W RAMie (wskaźnik stosu?) czy sprzętowy zestaw rejestrów LIFO? A może jeden rejestr śladu? Tego też nie widać. Jakie tryby adresowania przewidujesz? Nawet najprostsze konstrukcje ogromnie zyskują gdy mogą adresować pamięć pośrednio przez rejestr (indirect) - dopiero wtedy, gdy można wyliczać adresy daje się sensowne obsługiwać tablice itp struktury danych. Czy jakoś to przewidujesz? Moim zdaniem różnorodność metod adresowania jest nawet ważniejsza niż rozbudowane funkcje ALU. A propos: czy mógłbyś przedstawić proponowaną listę instrukcji wraz z możliwymi trybami adresowania? Czy przewidujesz jakieś instrukcje zatrzymujące CPU choćby do przyjścia przerwania (np. IDLE) bo wiesz, obniżanie poboru mocy to dziś priorytet. Czy mógłbyś jakoś pokrótce odpowiedzieć na powyższe zanim zrealizujesz ten projekt? BTW: Przerwania rzeczywiście dzielimy na zewnętrzne i wewnętrzne, ale to nie jest tak jak opisałeś. Zewnętrzne to wszystkie te , które przychodzą ze źródeł niezależnych (asynchronicznych) od programu: peryferia, piny I/O itp a wewnętrzne to te, które zgłasza sobie niejako sam procesor: dzielenie przez zero, naruszenie ochrony pamięci, nieprawidłowy kod operacyjny instrukcji czy jawne wykonanie instrukcji przerwania (np. zmieniającego poziom przywilejów lub robiącego breakpoint). 2 Link do komentarza Share on other sites More sharing options...
rafal2808 Styczeń 2, 2020 Autor tematu Udostępnij Styczeń 2, 2020 Na ten moment komunikacja z rejestrami realizowana jest właśnie za pomocą osobnych instrukcji. Myślę że w przyszłych projektach wszystko realizowane będzie właśnie na zasadzie większych bloków a komunikacja zostanie ujednolicona. W mojej wizji rejestr A pełni funkcję czegoś na wzór rejestru wejściowego. Dane na początek zapisywane są tam dopiero później rozsyłane są dalej. W taki sam sposób przesyłany jest rozkaz dla ALU zapisywany docelowo w rejestrze C. Jako iż wszystko działa w sposób wspomniany wyżej nie mamy możliwości zmiany zawartości rejestru poprzez jeden rozkaz. Należy wprowadzić odpowiedni rozkaz dla ALU a następnie wynik zapisać w docelowym rejestrze. Procesor jest 8 bitowy. Pamięć ROM posiada strukturę 2048x16 natomiast RAM 256x8. Raczej kluczowa jest zajętość FPGA. Układ na płytce Elbert v2 nie dysponuje dużą ilością zasobów, a przy syntezie prostszego projektu tak wygląda ich zużycie. Co do układu przerwań to będę eksperymentował. Na początek myślę że zaprojektuje coś prostego na zasadzie wystąpi przerwanie->skok do podprogramu->powrót. Na razie świadomie rezygnuje z zabezpieczenia się przed sytuacjami typu w trakcie obsługi przerwania wystąpi kolejne. Adresowanie bezpośrednie, listę instrukcji umieszczę wkrótce. Na razie funkcji zatrzymania CPU nie planuję. BTW: Uwaga co do przerwań jak najbardziej słuszna. 1 Link do komentarza Share on other sites More sharing options...
Popularny post marek1707 Styczeń 2, 2020 Popularny post Udostępnij Styczeń 2, 2020 (edytowany) Dzięki za odpowiedzi. Zapytałeś w mailu jaką książkę polecam żeby o procesorach dowiedzieć się wiecej, ale odpowiem tutaj. Być może jest więcej chętnych do poszerzenia swojej wiedzy w tym temacie i ktoś tam jeszcze wynajdzie tę staroć na aukcji. Myślę, że swoją zabawę powinieneś zacząć od przeglądu istniejących proocesorów. I to nie od spisania typów i poczytania o nich w Wikipedii, ale od zdobycia jak najbardziej szczegółowych informacji o nich i przymierzeniu się do pisania programów w asemblerach tych układów. To daje niesamowitą wiedzę o tym jak procesor może/powinien być zbudowany i co musi mieć a bez czego można się obejść. Dobrą książką jest cegła Klingmana "Projektowanie systemów mikroprocesorowych" - o ile pamiętam, bo zaczyna od podstaw i pokazuje jak projektować sprzęt dla bardzo starych konstrukcji typu 8008, 6502 czy 8080. Przy okazji omawia je szczegółowo, także przez porównywanie pewnych podsystemów (pamięć, I/O) ze sobą. Na takich przykładach nauczysz się najwięcej. Wbrew pozorom te klasyczne już dzisiaj projekty były bradzo dobrze zrobione. Listy instrukcji były wysoce optymalne (także ze względu na ograniczoną liczbę tranzystorów) a rożnorodność architektur daje dobry przegląd tego jak można podejść do realizacji bądź co bądź tego samego: do stworzenia kompletnej (wg Turinga) maszyny cyfrowej. Możesz zacząć od prymitywnego 4004 - jest na jego temat mnóstwo wiedzy w sieci, łącznie z modelami w VHDL czy Verilogu, symulatorami na PC, asemblerami itp. To samo o 8080 - koniu pociągowym wczesnej mikrokomputeryzacji świata. Musisz mieć to w małym palcu, żeby rozumieć jak architektura przekłada się na listę instrukcji i możliwości operacyjne procesora. Dopiero potem przyjdzie czas na peryferia czy co bardziej skomplikowane bloki jak MMU, DMA, system przerwań wektoryzowanych czy instrukcje/stany uprzywilejowane. Procesory dzisiaj to nieprawdopodobnie skomplikowane maszyny, ale żeby je zrozumieć i móc projektować swoje własne (a nie tylko błądzić na oślep mozolnie ucząc się na własnych błędach) musisz poznać te pierwsze. Proponuję, byś po zgromadzeniu informacji na temat jakiegoś 4-bitowca (może być 4004 lub 4040) i kilku 8-bitowych kostek (np. 8008, 8080 i powiedzmy 6800 lub 6502) spróbował napisać w ich asemblerach jakieś wspólne funkcje np. konwersję bin->ASCII, jakieś sortowanie (tablicy liczb a może słów), wyszukiwanie wzorca (parsowanie) linii tekstu czy nawet zegarek z datą. To z pewnością otworzy Ci oczy na to jak pisze się kod dla typowego procesora i pokaże jakie dana konstrukcja ma wady a jakie zalety. Poznasz tryby adresowania, ich siłę lub ból braku tych co fajniejszych. Do tego możesz dorzucić jakis jednoukładowiec (np. pierwszy mikorokontroler 8035/8048 albo od razu 8051) plus coś "nowszego" z architekturą RISC np. jądro AVR lub któryś wczesny PIC. Celowo nie piszę tu o dużych maszynach typu 8086 czy ARM, bo to już wyższa szkoła jazdy a bez podstaw wyssanych z klasyki nic Ci nie da wykonywanie 100 milionów instrukcji na sekundę. Znając wiele standardowych architektur będziesz miał szansę świadomej oceny: co się udało a co było takie sobie. Co było pomysłem wyprzedzającym konkurencję a co smutnym ograniczeniem koniecznym ze względu na ówczesną technologię. Dopiero wtedy będzie można rozmawiać o własnych, niestandardowych pomysłach czy ciekawych rozszerzeniach. Teraz nawet trudno mi komentować to co napisałeś, bo np. jak zrozumieć zdanie: 3 godziny temu, rafal2808 napisał: zaprojektuje coś prostego na zasadzie wystąpi przerwanie->skok do podprogramu->powrót Przecież z przerwaniem ma tu coś wspólnego jedynie "skok do podprogramu" - wymuszony przez sekwencer i właśnie o to pytałem, jak chcesz to zrealizować a dokładniej gdzie chcesz zapamiętać ślad. Po zapamiętaniu kontekstu (cokolwiek to w danej architekturze znaczy) i przeładowaniu PC (jakkolwiek się to w danej architekturze wykona) procesor kontynuuje pracę jakby nic się nie stało a jedynym zadaniem logiki było bezbolesne "wstrzyknięcie" w ciąg wykonywanych instrukcji właśnie skoku ze śladem (CALL?). Ew. możesz sprzętowo blokować system przerwań dzięki czemu masz natywnie tylko jeden ich poziom. Tak czy tak sensowny procesor (czyli nie akademickie rozważanie o bramkach tylko wykonujący rzeczywiste programy układ) powinien mieć jakiś stos a ten wiąże się tak z prodprogramami jak i z systemem przerwań. Możesz to rozdzielić i skoki ze śladem zrobić bardzo proste (np. tylko shadow register dla PC) z programowym wsparciem zachowywania/odtwarzania kontekstu i nawet programowym wskaźnikiem stosu, a możesz w sprzęcie zaszyć dużo więcej. To Twoje decyzje, ale nie wiedząc jakie są w ogóle są możliwości jak możesz je podejmować świadomie? Były procesory niemające przerwań wcale (4004), były takie ze sprzętowym stosem o zaledwie kilku poziomach i to przeznaczonym jedynie na adresy powrotu (8035/8048), były takie ze stosem ograniczonym do małego obszaru RAMu (8051) i były takie z pełnym, 16-bitowym SP (8080 i następcy). Jedne miały tylko podstawowe tryby adresowania (8008) a inne miały ich całą feerię (Z-80), mimo że i jedne i drugie były stosunkowo prymitywne i wolne. Na pewno zauważysz po bliższym przyjrzeniu się, że projektanci nawet tych prostszych chipów zostawiali nam furtki dodając specjalne instukcje umożliwiające programową emulację brakujących trybów. I to było piękne.. Dobra, znowu popłynąłem.. sorki za dłużyzny. Także, tego, do roboty 🙂 Edytowano Styczeń 2, 2020 przez marek1707 3 1 Link do komentarza Share on other sites More sharing options...
Popularny post FlyingDutch Styczeń 3, 2020 Popularny post Udostępnij Styczeń 3, 2020 14 godzin temu, marek1707 napisał: Dzięki za odpowiedzi. .... Przecież z przerwaniem ma tu coś wspólnego jedynie "skok do podprogramu" - wymuszony przez sekwencer i właśnie o to pytałem, jak chcesz to zrealizować a dokładniej gdzie chcesz zapamiętać ślad. Po zapamiętaniu kontekstu (cokolwiek to w danej architekturze znaczy) i przeładowaniu PC (jakkolwiek się to w danej architekturze wykona) procesor kontynuuje pracę jakby nic się nie stało a jedynym zadaniem logiki było bezbolesne "wstrzyknięcie" w ciąg wykonywanych instrukcji właśnie skoku ze śladem (CALL?). Ew. możesz sprzętowo blokować system przerwań dzięki czemu masz natywnie tylko jeden ich poziom. Tak czy tak sensowny procesor (czyli nie akademickie rozważanie o bramkach tylko wykonujący rzeczywiste programy układ) powinien mieć jakiś stos a ten wiąże się tak z prodprogramami jak i z systemem przerwań. Możesz to rozdzielić i skoki ze śladem zrobić bardzo proste (np. tylko shadow register dla PC) z programowym wsparciem zachowywania/odtwarzania kontekstu i nawet programowym wskaźnikiem stosu, a możesz w sprzęcie zaszyć dużo więcej. To Twoje decyzje, ale nie wiedząc jakie są w ogóle są możliwości jak możesz je podejmować świadomie? Cześć, zgadzam się tutaj z Markiem, że jeśli już implementujesz system przerwań warto/trzeba zaimplementować stos - czasami same zapamiętanie wartości PC (adresu powrotu) nie wystarcza, trzeba też zapamiętać wartości niektórych/wszystkich rejestrów. Pomyśl też o wyłączaniu/włączaniu przerwań (często jest to niezbędne). Ideałem byłaby też możliwość maskowania poszczególnych przerwań (za pomocą ustawiania odpowiednich bitów specjalnego rejestru). Myślę, że dobrym punktem wyjścia jest zapoznanie się z architekturą Intela 8080 - to prosty 8-mio bitowy procesor, który ma dość dobrze zaprojektowaną architekturę. To na co zwrócił uwagę Marek odnośnie trybów adresowania też jest bardzo ważne tryb bezpośredni to trochę za mało. Pozdrawiam 3 Link do komentarza Share on other sites More sharing options...
marek1707 Styczeń 3, 2020 Udostępnij Styczeń 3, 2020 11 minut temu, FlyingDutch napisał: czasami same zapamiętanie wartości PC (adresu powrotu) nie wystarcza W zasadzie wystarcza, bo z punktu widzenia sprzętu PC to jedyny zasób którego program rozpoczynający wykonywanie ISR nie jest w stanie odtworzyć. Jak rozumiem miałeś na myśli "niewystarczanie:" w sensie niszczenia ogólnego stanu procesora w trakcie wykonywania obsługi przerwania. Niestety tu mamy kolejny przykład ważnej decyzji: jeżeli sprzęt będzie zapisywał na stos dużo rzeczy, to będzie to kosztowało dużo czasu więc reakcja procesora na przerwanie będzie wolna. Pierwsza instrukcja naszego kodu ISR wykona się dopiero po dokonaniu iluś tam zapisów do pamięci, a nie zawsze jest to konieczne. Można sobie wyobrazić przerwanie, którego obsługa składa się z jednej instrukcji, np. mając do dyspozycji wiele rejestrów, jeden z nich można globalnie zarezerwować na wskaźnik w jakimś buforze. Przykładowy ADC zgłasza koniec konwersji, sprzęt zapisuje tylko PC na stos, wykonuje pierwszą instrukcję z ISR która polega na a) przeładowaniu słowa danych z ADC do pamięci pod adres umieszczony w umówionym rejestrze i b) jego automatycznej postinkrementacji, po czym następuje powrót do przerwanego wątku (instrukcja RET lub RETI odblokowujące system przerwań). To oczywiście skrajny przykład, ale pokazujący, że być może przerzucenie na sprzęt zapisywania stanu całego procesora jest przesadą. Architektura oraz lista instrukcji procesora muszą być jednak przemyślane tak, by wspierały takie rozwiązania. Co więcej, PC nie musi być zapisywany na stos.Jeśli zrobisz rejestr leżący tuż obok PC to tam możesz zapisać jego aktualną zawartość i już w następnym cyklu maszynowym zaadresować pamięć wektorem pierwszej instrukcji ISR. Wtedy to programiście (ew.kompilatorowi) zostawiasz decyzję co do zapisu kontekstu na stos. I znów: lista instrukcji musi to wspierać, bo program musi mieć dostęp do rejestru shadow-PC aby jego zawartość móc przesłać gdzieś w bezpieczne miejsce. Ten sam mechanizm, ale w drugą stronę można wykorzystać do powrotu: jakaś instrukcja zdejmuje ze stosu (lub z innego bezpiecznego miejsca) rejestr shadow-PC a właściwy RET przeładowuje to do PC. Co więcej (po raz drugi) operacje na tym drugim rejestrze nie muszą być rzeczywistą wymianą danych między PC a shadow. Wystarczy przecież zmieniać jednobitową flagę określającą który z tych rejestrów jest aktualnie prawdziwym licznikiem rozkazów. Idźmy dalej: w 8035 mamy 12-bitowy PC a 8-poziomowy stos jest umieszczony w 8-bitowej pamięci więc podczas cyklu potwierdzania przerwania procesor zapisuje nie tylko PC ale też 4 bity (flagi) stanu ALU (tzw. PSW - Processor Status Word). Sprzęt robi zatem tylko to co niezbędne a program może zrobić resztę, np. zachować akumulator. Co ciekawe mamy tam 2 banki po 8 rejestrów przełączanych jedną instrukcją więc ISR może błyskawicznie zmienić sobie kontekst na bank alternatywny, podziałać na nim a przed powrotem (specjalna instrukcja RETN) odtworzyć flagi powracając tym samym do oryginalnego banku rejestrów. I to wszystko bez użycia stosu. Co prawda zmusza to do jednopoziomowego systemu przerwań (choć są mechanizmy by to rozszerzyć), ale w małych procesorkach to się sprawdza. Potwierdzeniem tego jest rozwiązanie zastosowane w następcy, czyli 8051. Tam, dostaliśmy już 4 banki rejestrów także bardzo szybko przełączane, no i system przerwań ma 4 poziomy.. To tylko kilka przykładów na to jak bardzo architektura procesora musi być przemyślana i jak ściśle współpracuje z listą rozkazów. Robiąc taki projekt warto narysować sobie model sprzętu z punktu widzenia programisty: bez tych wszystkich strzałek, magistral czy multiplekserów. Mamy wtedy czysty obraz dostępnych rejestrów, mapę pamięci itp i wtedy porównać to z planowaną listą instrukcji, która nie powinna być kulą u nogi a szansą na sprawną realizację algorytmów. A żeby taką się stała trzeba zwyczajnie napisać trochę nietrywialnych funkcji/programów i zmodyfikować ja tak, by w danej architekturze była optymalna. W prostszych przypadkach wystarczy mieć trochę doświadczenia 😀 bo na tym najniższym poziomie procesory robią jakieś bardzo podstawowe rzeczy: przesuwają bloki pamięci, porównują je, liczą arytmetykę wielokrotnej precyzji, odliczają pętle for z liczników czy wołają podprogramy z przekazywaniem do nich parametrów i odzyskiwaniem wyników. W każdym z takich przypadków architektura i lista instrukcji muszą ze sobą ściśle współgrać. BTW: Osobnym problemem jest właśnie. przekazywanie argumentów do funkcji. Nie licząc jakichś egzotycznych pomysłów, robimy to przez stos albo przez rejestry. W każdym z przypadków potrzebne są instrukcje do sprawnej obsługi "stałych fragmentów gry": tworzenia, dostępu do i niszczenia ramek na stosie. W przypadku stosu przydaje się adresowanie bazowe z możliwością albo adresowania względem SP (np. coś w rodzaju MOV A, [SP+6] ) albo przeładowania jego zawartości do któregoś z rejestrów ogólnego przeznaczenia. Jest to szczególnie ważne w procesorach z małą liczbą rejestrów. Moim zdaniem minimalna architektura 8-bitowej maszynki to coś w rodzaju Motoroli 6800 (dwa akumulatory i jeden rejestr indeksowy) albo któryś z jego "dzieci" np. MOS Technology 6502 (jeden akumulator ale za to dwa rejestry indeksowe). Nie ma co wyważać dawno otwartych drzwi i po prostu podglądać jakie sprytne rzeczy powymyślali projektanci tamtych układów. W szczególności chodzi mi o tryby adresowania: stronę zerową i dwie zupełnie różne koncepcje używania rejestrów indeksowych. 2 Link do komentarza Share on other sites More sharing options...
FlyingDutch Styczeń 3, 2020 Udostępnij Styczeń 3, 2020 (edytowany) 31 minut temu, marek1707 napisał: 1) W zasadzie wystarcza, bo z punktu widzenia sprzętu PC to jedyny zasób którego program rozpoczynający wykonywanie ISR nie jest w stanie odtworzyć. Jak rozumiem miałeś na myśli "niewystarczanie:" w sensie niszczenia ogólnego stanu procesora w trakcie wykonywania obsługi przerwania. Niestety tu mamy kolejny przykład ważnej decyzji: jeżeli sprzęt będzie zapisywał na stos dużo rzeczy, to będzie to kosztowało dużo czasu więc reakcja procesora na przerwanie będzie wolna. 2) Moim zdaniem minimalna architektura 8-bitowej maszynki to coś w rodzaju Motoroli 6800 (dwa akumulatory i jeden rejestr indeksowy) albo któryś z jego "dzieci" np. MOS Technology 6502 (jeden akumulator ale za to dwa rejestry indeksowe). Nie ma co wyważać dawno otwartych drzwi i po prostu podglądać jakie sprytne rzeczy powymyślali projektanci tamtych układów. W szczególności chodzi mi o tryby adresowania: stronę zerową i dwie zupełnie różne koncepcje używania rejestrów indeksowych. Cześć Marek, 1) Myślałem o automatycznym zapamiętaniu na stosie jedynie wartości PC (adres powrotu). Oraz zaimplementowaniu instrukcji CPU: PUSH rejestr i POP rejestr (niech programista sam decyduje, czy poza adresem powrotu chce zapamiętać coś jeszcze. 2) Akurat Intel8080 i MOS6502 to dwa pierwsze procesory, które poznałem. Intel 8080 był w "walizkowym" komputerku z klawiaturą heksadecymalną i diodkami LED na magistralach adresowych i danych (to był pierwszy układ z CPU do jakiego miałem dostęp w drugiej klasie technikum w pracowni informatycznej). Zaczynałem naukę programowania właśnie od programowania w assemblerze Intela 8080 - rozkazy tłumaczyło się "ręcznie" korzystając z tabelki w książce (lista rozkazów intela 8080) i wprowadzało jako hex'y z klawiatury. MOS 6502 pojawił się w pracowni informatycznej rok później razem z komputerami Atari800-XL. Jego też programowałem najpierw w assemblerze, a potem w assemblerze i Basic'u (razem). Zgadzam się z Tobą, że jego architektura (MOS6502) była dużo lepsza od Intela 8080 (mało rejestrów, dużo trybów adresowania, strona zerowa pamięci i uproszczona lista rozkazów), Trzeba jednak brać pod uwagę, że Rafał dopiero zaczyna swoją przygodę z budową własnego CPU i rozumiem, że zaczyna implementację od najprostszych rozwiązań. Nie sądzę, aby kiedykolwiek pisał kompilator np. języka C do swojego CPU 😉 Dużo można podpatrzeć (budowa soft-procesorów) na stronie Opencores.org, tam są projekty z kilkudziesięcioma soft-cpu od 4-bitowych do OpenSparc. Pozdrawiam. Edytowano Styczeń 3, 2020 przez FlyingDutch 2 Link do komentarza Share on other sites More sharing options...
marek1707 Styczeń 3, 2020 Udostępnij Styczeń 3, 2020 (edytowany) W żadnym razie nie chodziło mi o niszczenie zaangażowania Kolegi @rafal2808 a raczej o pokazanie, a) że jest mnóstwo dobrych przykładów, b) że nawet prosty procesor jest o wiele bardziej skomplikowanym projektem niż się wydaje na pierwszy rzut oka. Siadając do komputera mamy zwykle ogromną ochotę od razu zacząć pisać program albo tworzyć kod VHDL a nie tędy droga. Bez przemyślenia na pewno też coś powstanie, ale bez żartów - trudno będzie nazwać procesorem coś wykonującego kilka przypadkowo zmyślonych instrukcji składających się na mruganie LEDem. OK, to pewnie spełnia wymogi formalne definicji słowa procesor, ale spełnia je także maszynka do drylowania wiśni. I dlatego chętniej zobaczyłbym projekt architektury (ten z punktu widzenia programisty) i listę instrukcji - bo to daje już posmak tego co można będzie zrobić pisząc pierwsze programy - niż obrazek z licznikami, pamięciami i strzałkami a co gorsza od razu kod VHDL. Rozumiem, że to nie wyścig na Księżyc i jako amatorzy musimy zaczynać od prostych rzeczy, ale nawet robiąc coś 4- czy nawet 1-bitowego dobrze jest mieć jakiś plan. Nie polegający na zwykłym "zrobię sobie procesor", tylko jakiś bardziej precyzyjny w szerszym kontekście. Inaczej nauka języka i konkretnego środowiska (bo jak rozumiem głównie o to tu chodzi) nie będzie efektywna. A jedynym sprawdzianem Twoich umiejętności jest przecież porównanie. Możesz całą zimę spędzić na siłowni i basenie, od marca przesiąść się na rower i z kopyta ostro jeździć ale cały ten trening będzie nic nie wart dopóki nie porównasz swoich wyników z osiągnięciami innych ludzi. Dlatego dopiero wyścig weryfikuje co umiesz. Tutaj tak samo: pomysł typu "zrobię 4004 wykonujący jego natywny kod binarny" jest dobrym wyzwaniem, ale dużo lepszym jest "ale w mniejszej liczbie taktów zegara" (co akurat w przypadku tego 16-pinowego CPU z 4-bitowym kontaktem ze światem jest bardzo proste). A w przypadku architektur własnych - jak ta tutaj - świetną oceną mogą być benchmarki starych procesorów. Co więcej, były one wręcz stworzone do pisania w językach asemblera więc nauczenie się kilku z nich choćby dla potrzeb stworzenia własnych testów prędkości byłoby kolejnym plusem tej zabawy. Jeżeli Twoje 8-bitowe cudo zrobione na nowoczesnym FPGA i używające w zasadzie nieograniczonej liczby bramek będzie wolniej (w sensie liczby taktów zegara) sortowało blok pamięci albo wolniej liczyło iloraz dwóch liczb 32-bitowych lub zmiennoprzecinkowych niż 8080 to wiesz, nie ma się czym chwalić ani z czego cieszyć. Gdzieś popełniłeś poważne błędy w projekcie: albo w architekturze, albo w liście instrukcji a goście sprzed kilkudziesięciu lat zrobili to zwyczajnie lepiej. No chyba, że założenie było inne, np. "moje 8-bitowe CPU będzie miało wyłącznie 1-bitowe magistrale szeregowe" - bo takie procesory też były, albo może "mój procesor będzie natywnie wykonywał kod Brainfuck'a" - to też już było, albo "skoro każdy układ logiczny można zsyntetyzować przy użyciu bramek NAND to moje CPU będzie miało1-bitowe ALU z jedną instrukcją - zgadnijcie jaką". Cóż, zmyślam na poczekaniu... Podsumowując: nie widzę sensu w implementacji czegokolwiek (niechby i procesora) bez postawienia sobie jasnych i weryfikowalnych założeń. Nie muszą to być wyzwania z kosmosu, ale na pewno nic trywialnego lub mglistego. I chętnie o takich założeniach mogę dyskutować. A tej uwagi o kompilatorze C nie bardzo rozumiem. Tworzenie kompilatorów jest dzisiaj zautomatyzowane, ale projektant sprzętu nie musi umieć ich pisać. Od tego są inni ludzie. Ma zrobić procesor, który nie ma wąskich gardeł i spełnia założenia (np. jeśli ma być programowany głównie w C to ma się niego dobrze pisać kompilatory - to też widać w architekturze) natomiast może i powinien przetestować swój procesor na wielu typowych programach/testach a do tego wystarczy asembler. Zaznaczam, że wciąż mówimy o małych, jednowątkowych maszynkach do nauko-zabawy w domu. BTW: Chyba pamiętam ten walizkowy system na 8080. EDIT: -------------------------------------- "Zgadzam się z Tobą, że jego architektura (MOS6502) była dużo lepsza od Intela 8080.." Hej, nigdzie tego nie napisałem. Wspomniałem o minimalnej, czyli prostej do implementacji nawet dla początkującego a dającej już frajdę w pisaniu programów. Edytowano Styczeń 3, 2020 przez marek1707 2 Link do komentarza Share on other sites More sharing options...
Pomocna odpowiedź
Bądź aktywny - zaloguj się lub utwórz konto!
Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony
Utwórz konto w ~20 sekund!
Zarejestruj nowe konto, to proste!
Zarejestruj się »Zaloguj się
Posiadasz własne konto? Użyj go!
Zaloguj się »