Skocz do zawartości
FlyingDutch

AVR Soft-CPU (ATMega103) - projekt Vivado dla FPGA Artix7

Pomocna odpowiedź

Napisano (edytowany)

Cześć,

postanowiłem zaimplementować na jednej z moich płytek FPGA - CmodA7 (z układem Artix7)  soft-procesor zgodny z rdzeniem ATmega103 i posiadający całkiem sporo układów peryferyjnych.

Oto strona projektu na portalu opencores.org:

https://opencores.org/projects/avr_core

UWAGA! - po pobraniu archiwum ze strony projektu znajdziemy dwie implementacje avr-core: w katalogu "trunk" -wersja 14 (Verilog) i w katalogu "web uploads" wersja 8 (VHDL). Ja wybrałem do implementacji wersję 8 VHDL. Oto zawartość katalogów ze źródłami dla wersji 8:

Catalogs01.thumb.png.8210cbcc976e4d3535c9e6308c73586c.png

Projekt jest dość leciwy i był zaimplementowany na starym układzie FPGA Virtex Xilinx'a. Niestety w plikach źródłowych były użyte prymitywy Xilinx'a dla układu Virtex (bloki pamięci BRAM 4K i magistarali 8 bit) co powodowało około 70-ciu błędów na etapie syntezy (bloki te nazywały się RAMB4_S8). Bloki pamięci Virtex'a zostały przeze mnie zastąpione blokami pamięci o identycznej budowie IP-Core Xilinx Vivado (BRAM memory), tak , że nie ma już żadnych błędów podczas fazy syntezy. UWAGA!:  projekt zajmuje 96 procent pamięci BRAM dla kostki FPGA Artix7 z płytki CmodA7 i z powodu potrzebnej ilości pamięci BRAM nie da się zaimplementować na płytkach Elbert v.2 (Spartan3) lub Mimas v.2 (spartan6).

Tutaj link do użytej przeze mnie w projekcie płytki FPGA Digilent CmodA7:

https://reference.digilentinc.com/reference/programmable-logic/cmod-a7/start?redirect=1id=cmod_a7/cm

Miałem też podczas fazy implementacji błąd routingu zegara dla modułu JTAG, aby go rozwiązać musiałem użyć dyrektywy:

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets TCK_IBUF]

W pliku user constraints (xdc) - tutaj pełna zawartość tego pliku dla płytki FPGA CmodA7:

## Clock signal 12 MHz
set_property -dict { PACKAGE_PIN L17   IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_14 Sch=gclk
create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports {clk}];

## Buttons
set_property -dict { PACKAGE_PIN A18   IOSTANDARD LVCMOS33 } [get_ports { nrst }]; #IO_L19N_T3_VREF_16 Sch=btn[0]

## GPIO Pins
## Pins 15 and 16 should remain commented if using them as analog inputs
set_property -dict { PACKAGE_PIN M3    IOSTANDARD LVCMOS33 } [get_ports { rxd }]; #IO_L8N_T1_AD14N_35 Sch=pio[01]
set_property -dict { PACKAGE_PIN L3    IOSTANDARD LVCMOS33 } [get_ports { txd }]; #IO_L8P_T1_AD14P_35 Sch=pio[02]

set_property -dict { PACKAGE_PIN A16   IOSTANDARD LVCMOS33 } [get_ports { porta[7] }]; #IO_L12P_T1_MRCC_16 Sch=pio[03]
set_property -dict { PACKAGE_PIN K3    IOSTANDARD LVCMOS33 } [get_ports { porta[6] }]; #IO_L7N_T1_AD6N_35 Sch=pio[04]
set_property -dict { PACKAGE_PIN C15   IOSTANDARD LVCMOS33 } [get_ports { porta[5] }]; #IO_L11P_T1_SRCC_16 Sch=pio[05]
set_property -dict { PACKAGE_PIN H1    IOSTANDARD LVCMOS33 } [get_ports { porta[4] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=pio[06]
set_property -dict { PACKAGE_PIN A15   IOSTANDARD LVCMOS33 } [get_ports { porta[3] }]; #IO_L6N_T0_VREF_16 Sch=pio[07]
set_property -dict { PACKAGE_PIN B15   IOSTANDARD LVCMOS33 } [get_ports { porta[2] }]; #IO_L11N_T1_SRCC_16 Sch=pio[08]
set_property -dict { PACKAGE_PIN A14   IOSTANDARD LVCMOS33 } [get_ports { porta[1] }]; #IO_L6P_T0_16 Sch=pio[09]
set_property -dict { PACKAGE_PIN J3    IOSTANDARD LVCMOS33 } [get_ports { porta[0] }]; #IO_L7P_T1_AD6P_35 Sch=pio[10]

set_property -dict { PACKAGE_PIN J1    IOSTANDARD LVCMOS33 } [get_ports { portb[7] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=pio[11]
set_property -dict { PACKAGE_PIN K2    IOSTANDARD LVCMOS33 } [get_ports { portb[6] }]; #IO_L5P_T0_AD13P_35 Sch=pio[12]
set_property -dict { PACKAGE_PIN L1    IOSTANDARD LVCMOS33 } [get_ports { portb[5] }]; #IO_L6N_T0_VREF_35 Sch=pio[13]
set_property -dict { PACKAGE_PIN L2    IOSTANDARD LVCMOS33 } [get_ports { portb[4] }]; #IO_L5N_T0_AD13N_35 Sch=pio[14]
set_property -dict { PACKAGE_PIN M1    IOSTANDARD LVCMOS33 } [get_ports { portb[3] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=pio[17]
set_property -dict { PACKAGE_PIN N3    IOSTANDARD LVCMOS33 } [get_ports { portb[2] }]; #IO_L12P_T1_MRCC_35 Sch=pio[18]
set_property -dict { PACKAGE_PIN P3    IOSTANDARD LVCMOS33 } [get_ports { portb[1] }]; #IO_L12N_T1_MRCC_35 Sch=pio[19]
set_property -dict { PACKAGE_PIN M2    IOSTANDARD LVCMOS33 } [get_ports { portb[0] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=pio[20]

set_property -dict { PACKAGE_PIN N1    IOSTANDARD LVCMOS33 } [get_ports { INTx[7] }]; #IO_L10N_T1_AD15N_35 Sch=pio[21]
set_property -dict { PACKAGE_PIN N2    IOSTANDARD LVCMOS33 } [get_ports { INTx[6] }]; #IO_L10P_T1_AD15P_35 Sch=pio[22]
set_property -dict { PACKAGE_PIN P1    IOSTANDARD LVCMOS33 } [get_ports { INTx[5] }]; #IO_L19N_T3_VREF_35 Sch=pio[23]
set_property -dict { PACKAGE_PIN R3    IOSTANDARD LVCMOS33 } [get_ports { INTx[4] }]; #IO_L2P_T0_34 Sch=pio[26]
set_property -dict { PACKAGE_PIN T3    IOSTANDARD LVCMOS33 } [get_ports { INTx[3] }]; #IO_L2N_T0_34 Sch=pio[27]
set_property -dict { PACKAGE_PIN R2    IOSTANDARD LVCMOS33 } [get_ports { INTx[2] }]; #IO_L1P_T0_34 Sch=pio[28]
set_property -dict { PACKAGE_PIN T1    IOSTANDARD LVCMOS33 } [get_ports { INTx[1] }]; #IO_L3P_T0_DQS_34 Sch=pio[29]
set_property -dict { PACKAGE_PIN T2    IOSTANDARD LVCMOS33 } [get_ports { INTx[0] }]; #IO_L1N_T0_34 Sch=pio[30]

set_property -dict { PACKAGE_PIN U1    IOSTANDARD LVCMOS33 } [get_ports { TMS }]; #IO_L3N_T0_DQS_34 Sch=pio[31]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets TCK_IBUF]
set_property -dict { PACKAGE_PIN W2    IOSTANDARD LVCMOS33 } [get_ports { TCK }]; #IO_L5N_T0_34 Sch=pio[32]
set_property -dict { PACKAGE_PIN V2    IOSTANDARD LVCMOS33 } [get_ports { TDI }]; #IO_L5P_T0_34 Sch=pio[33]
set_property -dict { PACKAGE_PIN W3    IOSTANDARD LVCMOS33 } [get_ports { TDO }]; #IO_L6N_T0_VREF_34 Sch=pio[34]
set_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports { TRSTn }]; #IO_L6P_T0_34 Sch=pio[35]

zmieniając zawartość pliku "user constraint" w projekcie (i typ FPGA w właściwościach projektu) powinno się dać uruchomić ten projekt na innych płytkach FPGA z ukłądem Artix7 (np. Arty).

Podejrzewam, że bład routingu zegara dla JTAG (pin TCK z top entity) może być specyficzny dla mojej płytki FPGA. Tak więc zamieszczam pełny syntetyzujący się bez błędów projekt AVR core w Vivado2018.2. Chciałbym jak najszybciej wypróbować ten projekt na zestawie FPGA, ale do wczytania programu do soft procesora AVR jest potrzebny programator JTAG dla układów AVR, którego aktualnie nie mam dostępnego.

Jeśli komuś chciałoby się wypróbować ten soft-procesor (z jakimś prostym programem dla AVR) i opisać to byłbym bardzo wdzięczny 😀

Ja będę to robił za parę dni jak będę miał dostęp do programatora JTAG dla AVR i wrócę z wyjazdu służbowego. Później chciałbym użyć tego CPU do wypróbowania "Vivado HLS" i przetłumaczenia kilku bibliotek dla Arduino (w języku C++) na VHDL, oraz rozbudowy tego układu AVR o układ VGA z możliwością wyświetlania danych alfa-numerycznych na ekranie monitora.

Tutaj opis portów top entity projektu:

entity top_avr_core_v8 is port(
                               nrst   : in    std_logic;
                               clk    : in    std_logic;
                               porta  : inout std_logic_vector(7 downto 0);
                               portb  : inout std_logic_vector(7 downto 0);
	                           -- UART 
	                           rxd    : in    std_logic;
	                           txd    : out   std_logic;
							   -- External interrupts
							   INTx   : in    std_logic_vector(7 downto 0); 
							   -- JTAG related signals
	                           TMS    : in    std_logic;
                               TCK	  : in    std_logic;
                               TDI    : in    std_logic;
                               TDO    : out   std_logic;
	                           TRSTn  : in    std_logic -- Optional JTAG input
							   );
end top_avr_core_v8;

A tutaj screen z Vivado po implementacji projektu:

VivadoImplOK.thumb.png.cea07b6dff916330f13d386363f766f7.png

No tak wszystko jest tylko nie dodałem projektu Vivado (2018.2). Robię to teraz:

AVR_ATMega103_SoftCPU01.zip

BTW: za jakiś czas będę też próbował zaimplementować ten "AVR Core" dla taniego zestawu FPGA Intela "CoreEP4CE10" z układem  Altera Cyclone IV  - patrz link:

https://kamami.pl/zestawy-uruchomieniowe/561809-coreep4ce10-plytka-z-ukladem-fpga-altera-ep4ce10f17c8n-z-rodziny-cyclone-iv.html

Pozdrawiam

Edytowano przez FlyingDutch
  • Lubię! 2

Udostępnij ten post


Link to post
Share on other sites
(edytowany)

Cześć,

rozwiązałem problem z pinem zegara dla programatora JTAG. Przeniosłem pin TCK z lokalizacji :

set_property -dict { PACKAGE_PIN W2    IOSTANDARD LVCMOS33 } [get_ports { TCK }]; #IO_L5N_T0_34 Sch=pio[32]

na pin W5 Artix'a (pin 36 GPIO) - jest to pin typu  MRCC i ma odpowiedni routing pomiędzy zegarem a portem I/O:

set_property -dict { PACKAGE_PIN W5    IOSTANDARD LVCMOS33 } [get_ports { TCK }]; #IO_L12P_T1_MRCC_34 Sch=pio[36]

Teraz mogłem z pliku 'user constraints" xdc usunąć dyrektywę:

#set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets TCK_IBUF]

i nie ma żadnych ostrzeżeń związanych z pinem zegara dla programatora JTAG. Tak więc poprawny plik "user constraints" xdc dla mojej płytki FPGA jest następujący:

## Clock signal 12 MHz
set_property -dict { PACKAGE_PIN L17   IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_14 Sch=gclk
create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports {clk}];

## Buttons
set_property -dict { PACKAGE_PIN A18   IOSTANDARD LVCMOS33 } [get_ports { nrst }]; #IO_L19N_T3_VREF_16 Sch=btn[0]

## GPIO Pins
## Pins 15 and 16 should remain commented if using them as analog inputs
set_property -dict { PACKAGE_PIN M3    IOSTANDARD LVCMOS33 } [get_ports { rxd }]; #IO_L8N_T1_AD14N_35 Sch=pio[01]
set_property -dict { PACKAGE_PIN L3    IOSTANDARD LVCMOS33 } [get_ports { txd }]; #IO_L8P_T1_AD14P_35 Sch=pio[02]

set_property -dict { PACKAGE_PIN A16   IOSTANDARD LVCMOS33 } [get_ports { porta[7] }]; #IO_L12P_T1_MRCC_16 Sch=pio[03]
set_property -dict { PACKAGE_PIN K3    IOSTANDARD LVCMOS33 } [get_ports { porta[6] }]; #IO_L7N_T1_AD6N_35 Sch=pio[04]
set_property -dict { PACKAGE_PIN C15   IOSTANDARD LVCMOS33 } [get_ports { porta[5] }]; #IO_L11P_T1_SRCC_16 Sch=pio[05]
set_property -dict { PACKAGE_PIN H1    IOSTANDARD LVCMOS33 } [get_ports { porta[4] }]; #IO_L3P_T0_DQS_AD5P_35 Sch=pio[06]
set_property -dict { PACKAGE_PIN A15   IOSTANDARD LVCMOS33 } [get_ports { porta[3] }]; #IO_L6N_T0_VREF_16 Sch=pio[07]
set_property -dict { PACKAGE_PIN B15   IOSTANDARD LVCMOS33 } [get_ports { porta[2] }]; #IO_L11N_T1_SRCC_16 Sch=pio[08]
set_property -dict { PACKAGE_PIN A14   IOSTANDARD LVCMOS33 } [get_ports { porta[1] }]; #IO_L6P_T0_16 Sch=pio[09]
set_property -dict { PACKAGE_PIN J3    IOSTANDARD LVCMOS33 } [get_ports { porta[0] }]; #IO_L7P_T1_AD6P_35 Sch=pio[10]

set_property -dict { PACKAGE_PIN J1    IOSTANDARD LVCMOS33 } [get_ports { portb[7] }]; #IO_L3N_T0_DQS_AD5N_35 Sch=pio[11]
set_property -dict { PACKAGE_PIN K2    IOSTANDARD LVCMOS33 } [get_ports { portb[6] }]; #IO_L5P_T0_AD13P_35 Sch=pio[12]
set_property -dict { PACKAGE_PIN L1    IOSTANDARD LVCMOS33 } [get_ports { portb[5] }]; #IO_L6N_T0_VREF_35 Sch=pio[13]
set_property -dict { PACKAGE_PIN L2    IOSTANDARD LVCMOS33 } [get_ports { portb[4] }]; #IO_L5N_T0_AD13N_35 Sch=pio[14]
set_property -dict { PACKAGE_PIN M1    IOSTANDARD LVCMOS33 } [get_ports { portb[3] }]; #IO_L9N_T1_DQS_AD7N_35 Sch=pio[17]
set_property -dict { PACKAGE_PIN N3    IOSTANDARD LVCMOS33 } [get_ports { portb[2] }]; #IO_L12P_T1_MRCC_35 Sch=pio[18]
set_property -dict { PACKAGE_PIN P3    IOSTANDARD LVCMOS33 } [get_ports { portb[1] }]; #IO_L12N_T1_MRCC_35 Sch=pio[19]
set_property -dict { PACKAGE_PIN M2    IOSTANDARD LVCMOS33 } [get_ports { portb[0] }]; #IO_L9P_T1_DQS_AD7P_35 Sch=pio[20]

set_property -dict { PACKAGE_PIN N1    IOSTANDARD LVCMOS33 } [get_ports { INTx[7] }]; #IO_L10N_T1_AD15N_35 Sch=pio[21]
set_property -dict { PACKAGE_PIN N2    IOSTANDARD LVCMOS33 } [get_ports { INTx[6] }]; #IO_L10P_T1_AD15P_35 Sch=pio[22]
set_property -dict { PACKAGE_PIN P1    IOSTANDARD LVCMOS33 } [get_ports { INTx[5] }]; #IO_L19N_T3_VREF_35 Sch=pio[23]
set_property -dict { PACKAGE_PIN R3    IOSTANDARD LVCMOS33 } [get_ports { INTx[4] }]; #IO_L2P_T0_34 Sch=pio[26]
set_property -dict { PACKAGE_PIN T3    IOSTANDARD LVCMOS33 } [get_ports { INTx[3] }]; #IO_L2N_T0_34 Sch=pio[27]
set_property -dict { PACKAGE_PIN R2    IOSTANDARD LVCMOS33 } [get_ports { INTx[2] }]; #IO_L1P_T0_34 Sch=pio[28]
set_property -dict { PACKAGE_PIN T1    IOSTANDARD LVCMOS33 } [get_ports { INTx[1] }]; #IO_L3P_T0_DQS_34 Sch=pio[29]
set_property -dict { PACKAGE_PIN T2    IOSTANDARD LVCMOS33 } [get_ports { INTx[0] }]; #IO_L1N_T0_34 Sch=pio[30]

set_property -dict { PACKAGE_PIN U1    IOSTANDARD LVCMOS33 } [get_ports { TMS }]; #IO_L3N_T0_DQS_34 Sch=pio[31]
set_property -dict { PACKAGE_PIN W5    IOSTANDARD LVCMOS33 } [get_ports { TCK }]; #IO_L12P_T1_MRCC_34 Sch=pio[36]
set_property -dict { PACKAGE_PIN V2    IOSTANDARD LVCMOS33 } [get_ports { TDI }]; #IO_L5P_T0_34 Sch=pio[33]
set_property -dict { PACKAGE_PIN W3    IOSTANDARD LVCMOS33 } [get_ports { TDO }]; #IO_L6N_T0_VREF_34 Sch=pio[34]
set_property -dict { PACKAGE_PIN V3    IOSTANDARD LVCMOS33 } [get_ports { TRSTn }]; #IO_L6P_T0_34 Sch=pio[35]

Pozdrawiam

Edytowano przez FlyingDutch
  • Lubię! 1

Udostępnij ten post


Link to post
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!

Gość
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...