L’ultimo tassello che manca per poter costruire il nostro sistema è la descrizione della matrice di connessione che decodifica l’indirizzo della transazione per selezionare il corretto dispositivo slave e indirizza verso il master le risposte di questi.
La figura 1 evidenzia la matrice di connessione in un sistema AMBA AHB-Lite di tipo single-master. Il significato dei segnali di ingresso/uscita è stato chiarito nei precedenti articoli discutendo le periferiche master e slave.
Si sono utilizzati un processo combinatorio per generare i prossimi valori delle variabili interne ed aggiornare le linee di uscite verso le periferiche master e slave, ed uno sequenziale per registrare i segnali interni. Questi sono raggruppati in un record di tipo internal la cui dichiarazione è evidenziata nel listato 1.
1. type internal is record 2. SlvIndex : SlaveIndex; — slave index 3. active : std_logic; — transfer in progress 4. error : std_logic; — access to not-mapped area 5. error_dly : std_logic; — access to not-mapped area. 6. end record;
Listato 1 |
Il segnale active è attivo durante l’intera fase dati; i segnali error ed error_dly, invece, servono a generare un risposta con errore qualora il master abbia iniziato un trasferimento verso un’area di memoria non associata ad alcuna periferica slave. Il segnale SlvIndex, infine, indica quale slave è stato selezionato per la transazione corrente; viene generato in maniera combinatoria decodificando l’indirizzo ma, a causa della natura pipelined del bus, deve essere registrato al termine della fase di indirizzamento per consentire il corretto multiplexing delle linee dati (in lettura) e di controllo (in lettura ed in scrittura) durante la successiva fase dati. Il listato 2 evidenzia la descrizione di tale logica di multiplexing.
1. — Drive Hready/Hresp Signal Signal 2. hready:=’1’; 3. hresp :=HRESP_OKAY; 4. hrdata:= slvo(r.SlvIndex).hrdata; 5. if r.active=’1’ then 6. hready:=slvo(r.SlvIndex).hready; 7. hresp :=slvo(r.SlvIndex).hresp; end if; 8. if r.error=’1’ then — first cycle for error response 9. v.error :=’0’; 10. v.error_dly:=’1’; 11. hready:=’0’; 12. hresp :=HRESP_ERROR; 13. end if; 14. if r.error_dly=’1’ then — snd cycle for error response 15. v.error_dly:=’0’; 16. hready :=’1’; 17. hresp :=HRESP_ERROR; 18. end if; 19. if hready=’1’ then 20. v.active:=’0’; end if;
Listato 2 |
Come si osserva, la linea dati viene appunto pilotata (riga 4) con il valore della periferica slave selezionata nella precedente fase di indirizzamento. Allo stesso modo sono multiplexati i segnali di controllo (riga 6-7) se è in corso (riga 5) la fase dati di un trasferimento; diversamente assumono i valori di default (riga 2-3). Se invece vi è una condizione di errore (riga 8), la periferica chiude la transazione con errore (riga 8-18). Si ricordi, come discusso nella prima parte del nostro tutorial presentando le caratteristiche generali del protocollo AHB-Lite, che tale procedura richiede due cicli di clock. Durante il primo periodo, viene segnalata la condizione di errore e viene estesa la fase dati in modo da consentire al master di abortire un eventuale trasferimento già iniziato; il secondo periodo termina invece il trasferimento. Durante la fase di indirizzamento, invece, la matrice di connessione deve decodificare l’indirizzo per generare opportunamente i segnali Hsel in ingresso ai dispositivi slave. Tale logica è descritta nel listato 3.
1. — Decode Address to drive Hsel 2. v.error := ‘1’; 3. for i in 0 to NAHBSLV-1 loop 4. if ( (IconConfig(i).BAddr xor msto.Haddr) 5. and IconConfig(i).Mask ) = 0 then 6. hsel_v(i) :=’1’; v.error:=’0’; 7. end if; 8. end loop; 9. if msto.htrans=HTRANS_IDLE then 10. v.error:=’0’; end if;
Listato 3 |
NAHBSLV rappresenta il numero di slave presenti nella particolare implementazione; la costante è definita all’interno del package ahb_pkg. IconConfig, invece, è un parametro di configurazione definito mediante un parametro generic presente nell’entità del modello. Il tipo di tale parametro è esplicitato nel listato 4.
1. type SlvMemAddr is record 2. BAddr : std_logic_vector(31 downto 0); 3. Mask : std_logic_vector(31 downto 0); 4. end record; 5. 6. type AHBIconConfig is array (NAHBSLV-1 downto 0) of SlvMemAddr;
Listato 4 |
Si tratta di un array di costanti che definiscono lo spazio di indirizzamento per ogni dispositivo slave. Tale spazio è definito mediante un indirizzo base ed una maschera. Nella decodifica di indirizzo (riga 4-5 del listato 3) solo i bit mascherati ad ‘1’ del campo indirizzo del bus AHB vengono confrontati con l’indirizzo base della periferica per generare il segnale di abilitazione. In questo modo, il valore del registro di maschera consente di definire la quantità di memoria allocata per la periferica; un valore di maschera pari a 0xFFFFF000, ad esempio, definisce un’area di dimensione 4 Kbyte. L’ultima sezione (listato 5) del processo combinatorio del modello implementa il latch del numero di periferica slave indirizzato ed eventualmente attiva la flag active nel caso sia stato istruito un trasferimento valido.
1. —Latch Slave Index for next 2. if hready=’1’ then 3. for i in 0 to NAHBSLV-1 loop 4. if hsel_v(i)=’1’ then v.slvIndex:=i; end if; 5. if msto.htrans/=HTRANS_IDLE then v.active:=’1’; end if; 6. end loop; 7. end if;
Listato 5 |
Architetture multi-master
Il bus AMBA AHB-Lite definisce per semplicità, come inizialmente rimarcato, una architettura single-master. Tuttavia, riprogettando opportunamente la matrice di connessione, può essere introdotto il supporto per applicazioni multi-master senza la necessità di modificare in alcun modo la descrizione delle diverse periferiche. Uno schema di connessione multi-master, in generale, ha lo scopo di realizzare canali di comunicazione paralleli e simultanei tra più master e slave. Alcuni dei vantaggi di tale soluzione sono la disponibilità di una maggiore banda passante per l’intero sistema ed il supporto per un’architettura più flessibile che non vincoli l’attribuzione delle risorse accessibili da ogni singolo master fin dalla fase di design hardware ma consenta di esplorare soluzioni diverse durante lo sviluppo dei software applicativi ed il debug. Lo svantaggio principale risiede, invece, nella maggiore complessità della matrice di connessione. La figura 2 mostra, come esempio, il caso più semplice di architettura multi-master con un sistema costituito da due master e due slave.
Ad ogni master è associato un layer per ognuno dei quali è prevista una logica di decodifica che permetta di individuare il dispositivo slave selezionato. Per ogni dispositivo slave, quindi, è istanziato un arbitro che seleziona il layer che può accedere alla periferica nel caso di richieste simultanee. In merito, lo standard non for nisce indicazioni particolari; la selezione può essere indistintamente basata su schemi di arbitraggio a priorità o di tipo round-robin. Nel caso in cui due layer tentino di accedere contemporaneamente allo stesso dispositivo, l’arbitro associato ne seleziona uno; supponiamo sia il master 1. I suoi segnali di indirizzo e controllo sono riportati in ingresso alla periferica slave. L’indice del master selezionato, inoltre, viene registrato internamente; sarà utilizzato durante la successiva fase nel caso di accessi in scrittura per multiplexare le linee dati in ingresso alla periferica slave. Allo stesso modo, nel momento in cui l’accesso del bus viene negato al master 2, i suoi segnali di indirizzamento e controllo vengono internamente latchati dalla matrice di connessione; nel successivo ciclo, contemporaneamente allo svolgimento della fase dati del trasferimento del master 1, saranno utilizzati per richiedere un nuovo trasferimento alla periferica. Durante tale periodo la linea hready del master 2 deve però essere tenuta inattiva per evitare che il master possa ritenere chiuso il trasferimento ed iniziarne uno successivo. L’architettura indicata può facilmente essere estesa ad un numero qualsiasi di porte master e slave; in molti casi tuttavia non si ha la reale necessità di una struttura così completa e complessa e quindi vengono adottate delle soluzioni semplificate. Uno dei esempi più frequenti riguarda un sistema caratterizzato da un certo numero di periferiche lente; piuttosto che associare ogni periferica del genere ad una porta delle matrice di connessione, i diversi moduli, come mostrato in figura 3 in merito ai dispositivi slave 1 e slave 2, possono essere raggruppati come se costituissero una sola interfaccia slave.
In altri casi, come per i moduli slave 4 e slave 5, alcune periferiche possono invece essere riservate ad un singolo master. Si pensi ad esempio ad un sistema multi-processore con memoria dati/programmi privata per ognuno e connessa soltanto al layer associato ed una memoria condivisa, invece, resa accessibile a tutti dalla matrice di connessione.