Skocz do zawartości

PicoBlaze dla Spartan 3 (Xilinx 8-bit Microcontroller) - Linki


FlyingDutch

Pomocna odpowiedź

Cześć,

jako, że chciałbym spróbować implementacji 8-mio bitowego Soft-CPU Xilinx'a PicoBlaze (w wersji dla FPGA Spartan 3) zrobiłem mały "research" w sieci i zamieszczam kilkanaście linków dot. tego tematu, które wydały mi się interesujące:

https://www.xilinx.com/products/intellectual-property/picoblaze.html

http://www.picoblaze.info/cores.html

https://forums.xilinx.com/t5/PicoBlaze-Archived/PicoBlaze-FAQ-What-are-typical-applications/td-p/689

http://www.eng.utah.edu/~cs3710/xilinx-docs/examples/s3esk_startup.pdf

https://www.xilinx.com/support/documentation/ip_documentation/ug129.pdf

http://www.se.rit.edu/~se463/ResearchProject/PicoBlaze/PicoBlazeHowTo-1.pdf

https://kevinpt.github.io/opbasm/

https://www.fautronix.com/en/fidex

https://www.fautronix.com/en/fidex-licenses

https://forums.xilinx.com/t5/PicoBlaze-Archived/bd-p/PicoBlaze

http://www.lemongrass-studio.net/main/node/60

http://www.eng.auburn.edu/~strouce/class/elec4200/Overview%20of%20PicoBlaze.pdf

http://www.eng.auburn.edu/~strouce/class/elec4200/picoblaze_productbrief.pdf

http://www.picoblaze.info/tools.html

Udało mi się znaleźć jeszcze trzy tutoriale (jak dokonać set-up'u PicoBlaze i zacząć pisać program w asemblerze), które teraz zamieszczam:

http://www.csee.usf.edu/~haozheng/teaching/cda4253/doc/picoblaze-tutorial.pdf

https://kevinpt.github.io/opbasm/rst/tutorial.html

http://www.se.rit.edu/~se463/ResearchProject/PicoBlaze/PicoBlazeHowTo-3.pdf

3-ci link ma nieaktualne linki, ale reszta może się przydać.

Jako, że niezbyt lubię tą fazę rozpoznawania tematu (odsiewanie linków dot. danego tematu, które wydają mi się wartościowe od nieistotnych) to zamieszczam zestaw linków, które wydają mi się przydatne dla takiego rozpoznania (może inni dzięki temu będą mogli pominąć tą niezbyt ciekawą fazę).

Jeśli udałoby mi się zaimplementować "PicoBlaze" na płytce "Elbert V2" to planuję opisać to w kilku artykułach (oczywiście jesli nikt mnie nie ubiegnie w tym temacie 🙄 )

Mały update: udało mi się zsyntetyzować "PicoBlaze" dla Spartana 3 (ze żródeł VHDL, bo są jeszcze źródła w Verilogu oraz "czarna-skrzynka" opis połączeń) mam tylko problem z generacją zawartości pamięci ROM z programem dla tego CPU bo dostarczony z proijektem assembler to program DOS i nie działa z moim Windows 10. Uchylę tylko rąbka tajemnicy, że po syntezie CPU zajmuje niecałe 180 LUT (z pamięcią programu 1024 słowa 18-to bitowe). Patrz obrazek poniżej:

Pozdrawiam

Link do komentarza
Share on other sites

Znalazłem kilka artykułów w EP, które omawiały jak zainstalować PicoBlaze na płytce Kamami:

https://ep.com.pl/files/2996.pdf

https://ep.com.pl/files/3005.pdf

https://ep.com.pl/files/3057.pdf

https://ep.com.pl/files/3066.pdf

Przykład omówiony w ostatniej części artykułu przerobiłem żeby pasował do płytki ElbertV2 i działa 🙂 - tzn. miga diodą trochę szybciej, bo zegar jest 12MHz zamiast niecałych 4MHz, ale to kosmetyczna zmiana.

U mnie użycie zasobów wygląda tak:

Jakby co mogę jutro wstawić kody programu.

  • Lubię! 1
Link do komentarza
Share on other sites

Znalazłem kilka artykułów w EP, które omawiały jak zainstalować PicoBlaze na płytce Kamami:

https://ep.com.pl/files/2996.pdf

https://ep.com.pl/files/3005.pdf

https://ep.com.pl/files/3057.pdf

https://ep.com.pl/files/3066.pdf

Przykład omówiony w ostatniej części artykułu przerobiłem żeby pasował do płytki ElbertV2 i działa 🙂 - tzn. miga diodą trochę szybciej, bo zegar jest 12MHz zamiast niecałych 4MHz, ale to kosmetyczna zmiana.

U mnie użycie zasobów wygląda tak:

Obrazek

Jakby co mogę jutro wstawić kody programu.

Cześć Elvis,

czy zawartość ROM generowałeś za pomocą assemblera "kcpsm3.exe" bo ja nie mogłem uruchomić tego programu pod Windows 10 (sprawdzę to na maszynie wirtualnej z Windows XP), albo poszukam innego assemblera dla PicoBlaze.

Jeśli zamieścisz źródła projektu z chęcią je wypróbuję.

Update: udało mi się wygenerować zawartość ROM z programem. Użyłem "Open PicoBlaze Assembler" ze strony:

https://kevinpt.github.io/opbasm/#

Jest napisany w Pythonie i można go zainstalować używając managera pakietów Pythona "pip". Może używać ROM_Templates z 'kcpsm3' (VHDL) więc jest spoko 🙄

Pozdrawiam

Link do komentarza
Share on other sites

Używam Linux-a, więc do generowania zawartości ROM-u używałem programu picoasm https://marksix.home.xs4all.nl/picoasm.html. Kod wymagał drobnych poprawek, poza tym działał bez problemu.

Wypróbowałem też KCPSM3 - działa pod DosBox-em. W sumie jest nawet łatwiej, bo uruchamia się bez problemu, a z wynikowego kodu nie trzeba usuwać nieużywanych sygnałów.

W każdym razie mój plik źródłowy prog_1.psm w asemblerze miał postać (kody są z artykułów EP):

;**************************************************************************************
; Stale uzyte w programie
;**************************************************************************************

CONSTANT led_signal       , 01    ; numer diody LED
CONSTANT led_port_nr      , 00    ; numer portu, do ktorego przylaczony jest LED
CONSTANT licznik          , 2F    ; do ilu bedziemy odliczac aby zmienic stan diody LED

;**************************************************************************************
; Rejestry specjalnego przeznaczenia
;**************************************************************************************
;
; s0                 ; rejestr uzyty do zliczania impulsow
; s1                 ; s1 – rejestr z wartoscia portu – 1
; s2                 ; s2 – rejestr z wartoscia portu – 0
;;============================================================================
;; Nieskonczona petla.
;;============================================================================

   __start:    LOAD s1, 01                 ; s1 <= 1
               LOAD s2, 00                 ; s2 <= 0

   start:      LOAD s0, licznik            ; ustaw licznik
               LOAD sA, sA                 ; instrukcja pusta

   petla1:     SUB s0, 01                  ; odejmij jeden
               COMPARE s0, 00              ; sprawdz, czy zero
               JUMP NZ, petla1             ; jesli nie skocz do petla1

               OUTPUT s1, led_port_nr      ; ustaw sygnal LED_cntrl na ‘1’

               LOAD s0, licznik            ; ustaw licznik

   petla2:     SUB s0, 01                  ; odejmij jeden
               COMPARE s0, 00              ; sprawdz, czy zero
               JUMP NZ, petla2             ; jesli nie skocz do petla2

               OUTPUT s2, led_port_nr      ; ustaw sygnal LED_cntrl na ‘0’

               JUMP start                  ; skocz na poczatek programu

Po kompilacji otrzymałem plik prog_1.vhd, który można bezpośrednio włączyć do projektu:

--
-- Definition of a single port ROM for KCPSM3 program defined by prog_1.psm
--
-- Generated by KCPSM3 Assembler . 
--
-- Standard IEEE libraries
--
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
--
-- The Unisim Library is used to define Xilinx primitives. It is also used during
-- simulation. The source can be viewed at %XILINX%\vhdl\src\unisims\unisim_VCOMP.vhd
--  
library unisim;
use unisim.vcomponents.all;
--
--
entity prog_1 is
   Port (      address : in std_logic_vector(9 downto 0);
           instruction : out std_logic_vector(17 downto 0);
                   clk : in std_logic);
   end prog_1;
--
architecture low_level_definition of prog_1 is
--
-- Attributes to define ROM contents during implementation synthesis. 
-- The information is repeated in the generic map for functional simulation
--
attribute INIT_00 : string; 
attribute INIT_01 : string; 
attribute INIT_02 : string; 
attribute INIT_03 : string; 
attribute INIT_04 : string; 
attribute INIT_05 : string; 
attribute INIT_06 : string; 
attribute INIT_07 : string; 
attribute INIT_08 : string; 
attribute INIT_09 : string; 
attribute INIT_0A : string; 
attribute INIT_0B : string; 
attribute INIT_0C : string; 
attribute INIT_0D : string; 
attribute INIT_0E : string; 
attribute INIT_0F : string; 
attribute INIT_10 : string; 
attribute INIT_11 : string; 
attribute INIT_12 : string; 
attribute INIT_13 : string; 
attribute INIT_14 : string; 
attribute INIT_15 : string; 
attribute INIT_16 : string; 
attribute INIT_17 : string; 
attribute INIT_18 : string; 
attribute INIT_19 : string; 
attribute INIT_1A : string; 
attribute INIT_1B : string; 
attribute INIT_1C : string; 
attribute INIT_1D : string; 
attribute INIT_1E : string; 
attribute INIT_1F : string; 
attribute INIT_20 : string; 
attribute INIT_21 : string; 
attribute INIT_22 : string; 
attribute INIT_23 : string; 
attribute INIT_24 : string; 
attribute INIT_25 : string; 
attribute INIT_26 : string; 
attribute INIT_27 : string; 
attribute INIT_28 : string; 
attribute INIT_29 : string; 
attribute INIT_2A : string; 
attribute INIT_2B : string; 
attribute INIT_2C : string; 
attribute INIT_2D : string; 
attribute INIT_2E : string; 
attribute INIT_2F : string; 
attribute INIT_30 : string; 
attribute INIT_31 : string; 
attribute INIT_32 : string; 
attribute INIT_33 : string; 
attribute INIT_34 : string; 
attribute INIT_35 : string; 
attribute INIT_36 : string; 
attribute INIT_37 : string; 
attribute INIT_38 : string; 
attribute INIT_39 : string; 
attribute INIT_3A : string; 
attribute INIT_3B : string; 
attribute INIT_3C : string; 
attribute INIT_3D : string; 
attribute INIT_3E : string; 
attribute INIT_3F : string; 
attribute INITP_00 : string;
attribute INITP_01 : string;
attribute INITP_02 : string;
attribute INITP_03 : string;
attribute INITP_04 : string;
attribute INITP_05 : string;
attribute INITP_06 : string;
attribute INITP_07 : string;
--
-- Attributes to define ROM contents during implementation synthesis.
--
attribute INIT_00 of ram_1024_x_18  : label is "000000004002C20054094000C001002FC10054044000C0011AA0002F02000101";
attribute INIT_01 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_02 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_03 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_04 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_05 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_06 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_07 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_08 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_09 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0A of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0B of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0C of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0D of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0E of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_0F of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_10 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_11 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_12 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_13 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_14 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_15 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_16 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_17 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_18 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_19 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_1A of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_1B of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_1C of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_1D of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_1E of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_1F of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_20 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_21 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_22 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_23 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_24 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_25 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_26 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_27 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_28 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_29 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_2A of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_2B of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_2C of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_2D of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_2E of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_2F of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_30 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_31 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_32 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_33 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_34 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_35 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_36 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_37 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_38 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_39 of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_3A of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_3B of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_3C of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_3D of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_3E of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INIT_3F of ram_1024_x_18  : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_00 of ram_1024_x_18 : label is "000000000000000000000000000000000000000000000000000000000ED4B500";
attribute INITP_01 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_02 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_03 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_04 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_05 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_06 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
attribute INITP_07 of ram_1024_x_18 : label is "0000000000000000000000000000000000000000000000000000000000000000";
--
begin
--
 --Instantiate the Xilinx primitive for a block RAM
 ram_1024_x_18: RAMB16_S18
 --synthesis translate_off
 --INIT values repeated to define contents for functional simulation
 generic map ( INIT_00 => X"000000004002C20054094000C001002FC10054044000C0011AA0002F02000101",
               INIT_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_07 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_08 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_09 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0A => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0B => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0C => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0D => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0E => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_0F => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_10 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_11 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_12 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_13 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_14 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_15 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_16 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_17 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_18 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_19 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_1A => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_1B => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_1C => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_1D => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_1E => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_1F => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_20 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_21 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_22 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_23 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_24 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_25 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_26 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_27 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_28 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_29 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_2A => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_2B => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_2C => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_2D => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_2E => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_2F => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_30 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_31 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_32 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_33 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_34 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_35 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_36 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_37 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_38 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_39 => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_3A => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_3B => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_3C => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_3D => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_3E => X"0000000000000000000000000000000000000000000000000000000000000000",
               INIT_3F => X"0000000000000000000000000000000000000000000000000000000000000000",    
              INITP_00 => X"000000000000000000000000000000000000000000000000000000000ED4B500",
              INITP_01 => X"0000000000000000000000000000000000000000000000000000000000000000",
              INITP_02 => X"0000000000000000000000000000000000000000000000000000000000000000",
              INITP_03 => X"0000000000000000000000000000000000000000000000000000000000000000",
              INITP_04 => X"0000000000000000000000000000000000000000000000000000000000000000",
              INITP_05 => X"0000000000000000000000000000000000000000000000000000000000000000",
              INITP_06 => X"0000000000000000000000000000000000000000000000000000000000000000",
              INITP_07 => X"0000000000000000000000000000000000000000000000000000000000000000")
 --synthesis translate_on
 port map(    DI => "0000000000000000",
             DIP => "00",
              EN => '1',
              WE => '0',
             SSR => '0',
             CLK => clk,
            ADDR => address,
              DO => instruction(15 downto 0),
             DOP => instruction(17 downto 16)); 
--
end low_level_definition;
--
------------------------------------------------------------------------------------
--
-- END OF FILE prog_1.vhd
--
------------------------------------------------------------------------------------

Z PicoBlaze dołączyłem plik kcpsm3.vhd, nie używam pozostałych dostarczanych z procesorem.

Plik główny ma postać:

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity pr_1 is Port
( clk : in  STD_LOGIC;
 rst : in  STD_LOGIC;
 LED_cntrl : out  STD_LOGIC);
end pr_1;

architecture Behavioral of pr_1 is
-- deklaracja KCPSM3
component kcpsm3 Port
( address : out std_logic_vector(9 downto 0);
 instruction : in std_logic_vector(17 downto 0);
 port_id : out std_logic_vector(7 downto 0);
 write_strobe : out std_logic;
 out_port : out std_logic_vector(7 downto 0);
 read_strobe : out std_logic;  
 in_port : in std_logic_vector(7 downto 0);
 interrupt : in std_logic;
 interrupt_ack : out std_logic;
 reset : in std_logic;
 clk : in std_logic);
end component;
-- deklaracja pamieci programu ROM
component prog_1 Port
( address : in std_logic_vector(9 downto 0);
 instruction : out std_logic_vector(17 downto 0);
 clk : in std_logic);
end component;
-- Sygnaly uzyte do polaczenia KCPSM3 z pamiecia programu ROM
signal address : std_logic_vector(9 downto 0);
signal instruction : std_logic_vector(17 downto 0);
signal port_id : std_logic_vector(7 downto 0);
signal out_port : std_logic_vector(7 downto 0);
signal in_port : std_logic_vector(7 downto 0);
signal write_strobe    : std_logic;
signal read_strobe     : std_logic;
signal interrupt       : std_logic;
signal interrupt_ack   : std_logic;
signal main_reset      : std_logic;
-- Sygnaly dodatkowe
signal clk_p       : std_logic;
signal CLK_licznik : integer range 0 to 3199;
begin
-- KCPSM3 and the program memory 
 processor: kcpsm3
port map(      address => address,
              instruction => instruction,
                  port_id => port_id,
             write_strobe => write_strobe,
                 out_port => out_port,
              read_strobe => read_strobe,
                  in_port => in_port,
                interrupt => interrupt,
            interrupt_ack => interrupt_ack,
                    reset => main_reset,
                      clk => clk_p);
 program_rom: prog_1
port map(      address => address,
              instruction => instruction,
                      clk => clk_p);

 interrupt <= interrupt_ack;
 main_reset <= not rst;

 LED_ustaw: process (clk_p, rst)
 begin
   if (rst = '0') then
     LED_cntrl <= '0';
   elsif clk_p'event and clk_p='1' then
     if ((port_id="00000000") and (write_strobe='1')) then
       LED_cntrl <= out_port(0);
     end if;
   end if;
 end process;

 CLK_ustaw: process (clk, rst)
 begin
   if (rst = '0') then
     CLK_licznik <= 0;
     clk_p <= '0';
   elsif clk'event and clk='1' then
     if (CLK_licznik >= 3199) then
       CLK_licznik <= 0;
       clk_p <= not clk_p;
     else
       CLK_licznik <= CLK_licznik + 1;
     end if;
   end if;
 end process;
end Behavioral;

Pozostaje już tylko dodać plik z ograniczeniami:

NET "clk"         LOC = P129  | IOSTANDARD = LVCMOS33 | PERIOD = 12MHz;
NET "rst"    		LOC = P80   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "LED_cntrl"   LOC = P46   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;

Efekt jest jak dla mnie imponujący - 15% zużytych slice-ów, a mamy działający procesor z 1K pamięci programu. Nic tylko dodać peryferia z ElbertV2 - diody, przyciski, wyświetlacze 7-segmentowe. A może nawet wyjście VGA i grę w pong-a w asemblerze 🙂

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

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

Używam Linux-a, więc do generowania zawartości ROM-u używałem programu picoasm https://marksix.home.xs4all.nl/picoasm.html. Kod wymagał drobnych poprawek, poza tym działał bez problemu.

Wypróbowałem też KCPSM3 - działa pod DosBox-em. W sumie jest nawet łatwiej, bo uruchamia się bez problemu, a z wynikowego kodu nie trzeba usuwać nieużywanych sygnałów.

Efekt jest jak dla mnie imponujący - 15% zużytych slice-ów, a mamy działający procesor z 1K pamięci programu. Nic tylko dodać peryferia z ElbertV2 - diody, przyciski, wyświetlacze 7-segmentowe. A może nawet wyjście VGA i grę w pong-a w asemblerze 🙂

Mi też ten program się skompilował, tylko użyłem innego assemblera (generuje kod VHDL do włączenia do projektu (ROM program) oraz plik .mem z binarną zawartością ROM.

Ja też jestem pod wrażeniem (na Githubie jest sporo przykładów programów dla PIcoBlaze - mnóstwo komunikacyjnych, jest nawet regulator PID. o który ktoś pytał jak zaimplementować na FPGA). Podobno można bez większych problemów rozszerzyć pamięć podręczną CPU z 64 do 256 słów i pamięć ROM do 4K słów 18-to bitowych, jest też sporo peryferiów do Pico.

Elvis: dziękuję za zamieszczony kod :->

Pozdrawiam

Link do komentarza
Share on other sites

Użycie soft procesorów to chyba dość popularne rozwiązanie. FPGA świetnie się sprawdza w przypadku modułów krytycznych czasowo (jak chociażby generowanie sygnałów dla VGA). Jednak wykonywanie obliczeń jest już bardzo "drogie", każda operacja zjada cenne zasoby. A mając soft procesor można raz zaimplementować ALU i można liczyć ile się chce, albo budować potwornie skomplikowaną maszynę stanów nie używając ani jednej dodatkowej bramki.

A pod względem praktycznym - mamy wtedy jeden scalak na płytce zamiast dwóch, a to czasem istotna różnica.

Ogólnie FPGA i procesory mają swoje zalety i wady, używając soft-procesora można tak podzielić projekt, żeby wykorzystać zalety obu rozwiązań.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.