Swordfish
# Swordfish

Swordfish era un microprocessore superscalare sviluppato da National Semiconductor e presentato nel 1990. Il microprocessore venne inizialmente sviluppato come successore del processore NS32532 (inizialmente il processore aveva il codice NS32732 ma in seguito prese il codice NS32764). Comunque il processore non fece parte della famiglia NS32, ma il suo progetto fu riutilizzato da un componente della famiglia CompactRISC. Il microprocessore aveva un progetto peculiare, esternamente eseguiva del codice macchina come fosse un comune microprocessore superscalare ma internamente operava come un processore LIW (long instruction word) con decodifica della cache istruzioni.

Verso la fine degli anni ottanta in Israele venne avviato lo sviluppo del processore. Il progetto prevedeva due pipeline per i dati interi chiamate A e B. Queste seguivano il classico progetto RISC a cinque stadi. La pipeline B era la pipeline primaria nel senso che poteva eseguire tutte le istruzioni mentre la pipeline A non poteva eseguire i salti e non poteva iniziare operazioni in virgola mobile. Tuttavia la prima istruzione decodificata e inviata alle pipeline veniva assegnata alla pipeline A mentre la seconda istruzione decodificata veniva assegnata alla pipeline B. L'esecuzione delle istruzioni avveniva simultaneamente tranne che la pipeline B non fosse bloccata per il rispetto di una dipendenza o per motivi similari. Un nuovo paio di istruzioni non poteva essere caricato fino a quando il precedente paio non avesse superato la fase di decodifica.

Un registro di scoreboard era utilizzato per controllare gli stalli WAR e WAW. In aggiunta venne inserito un registro FIFO di caricamento delle istruzioni nelle pipeline al fine di continuare l'esecuzione durante uno stallo della cache dati, ogni richiesta della cache richiedeva almeno 6 cicli di clock per essere soddisfatta. Il registro di scoreboard decodifica le istruzioni anche se alcune dipendenze dei dati non erano soddisfatte.

Ogni istruzione inviata alla pipeline B veniva inviata anche alla pipeline in virgola mobile in modo da poter iniziare a eseguire subito le istruzioni in virgola mobile. La pipeline in virgola mobile aveva cinque stadi oltre a quello di decodifica. La pipeline B operava in contemporanea con la pipeline in virgola mobile dato che questa non aveva una gestione delle istruzioni. La pipeline B controllava gli eventuali trap della pipeline in virgola mobile e introduceva uno stallo al fine di completare l'esecuzione con la pipeline in virgola mobile.

I primi processori funzionavano a 50 MHz di clock ed effettuavano una moltiplicazione intera in un ciclo di clock. La parte in virgola mobile era dotata di tre unità, una di somma, una di moltiplicazione e una di divisione.

La cache istruzioni del processore era particolare dato che oltre a caricare le istruzioni dalla memoria provvedeva a decodificarle in modo da poterle assegnare alle pipeline. Le istruzioni erano memorizzate già decodificate e pronte per essere inviate alle pipeline. La cache definiva anche eventuali dipendenze dai dati delle istruzioni e precalcolava l'indirizzo di destinazione dei salti. Veniva anche utilizzata un'unità di predizione dei salti.

Inizialmente il progetto prevedeva lo sviluppo di un set di istruzioni derivato dal NS32K minimale, dovevano essere inserite solo quelle fondamentali dal punto di vista delle prestazioni. La maggior parte delle istruzioni sarebbero state eseguite tramite emulazione, all'interno del processore era inclusa un'unità che convertiva le istruzioni nel set minimale gestito dalle pipeline. In seguito si decise di utilizzare un set di istruzioni più ampio in modo da non dover ricorrere troppo frequentemente all'emulazione. Le istruzioni native del processore erano utilizzate per creare una tabella di conversione con il set di istruzioni NS32K, le istruzioni convertite potevano essere di tre tipo:

* Primo tipo: Istruzioni eseguibili nativamente da una pipeline.
* Secondo tipo: Istruzione che richiedono due operazioni e quindi mappabili sulle due pipeline.
* Terzo tipo: Istruzioni che richiedono più di due operazioni elementari per essere eseguite.

Ogni istruzione in cache era dotata di due bit addizionali, il primo indicava la presenza di dipendenze dai dati, il secondo bit indicava la presenza di un'operazione emulata o eseguita in hardware.

