Skip to content

d-graz/Progetto-reti-logiche-2022

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

37 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

author date title
Davide Grazzani - *10660259*
A.A. 2021-2022
Progetto Reti Logiche

Progetto Reti Logiche A.A. 2021-2022

Voto : 30L

Attenzione: conversione da .tex a .md utilizzando pandoc. Si trova il contenuto originale (meglio formattato) nella cartella report/.

Codifiche Convoluzionali e Introduzione al Progetto

Una codifica convoluzionale è un tipo di codifica utilizzata per la Forward Error Correction (FEC) in sistemi di telecomunicazioni basati su canali monodirezionali.
Attraverso una codifica convouzionale si genera un codice convoluzionale, il quale trasforma ogni parola $P_1$ in una parola $P_2$. Definite $l_1 = lenght(P_1)$ e $l_2 = lenght(P_2)$ si definisce il rapporto $l_1/l_2$ come tasso di trasmissione del convolutore (rate); con $l_2 \geq l_1$. Inoltre, la trasformazione è una funzione degli ultimi $k$ bit in entrata, $k$ è quindi la lunghezza dei vincoli del codice.
Lo scopo del progetto è quello di implementare un componente hardware, tramite l'utilizzo del linguaggio di specifica dello hardware VHDL, in grado di interfacciarsi con una memoria ram e di applicare una codifica convoluzionale con $rate = \frac{1}{2}$ e $k = 3$.

Codificatore convoluzionale con $r = \frac{1}{2}$ e k = 3

Specifiche del progetto

Vengono fornite l'interfaccia del progetto, la specifica della memoria sulla quale interfacciarsi ed, infine, una limitazione temporale che impone che il modulo hardware computi correttamente con periodi di clock di almeno $clockPeriod_{req} = 100ns$.
Di seguito viene riportata l'interfaccia del modulo e l'interfaccia della memoria.

Interfaccia del progetto

entity project_reti_logiche is
    port (
        i_clk : in std_logic;
        i_rst : in std_logic;
        i_start : in std_logic;
        i_data : in std_logic_vector(7 downto 0);
        o_address : out std_logic_vector(15 downto 0);
        o_done : out std_logic;
        o_en : out std_logic;
        o_we : out std_logic;
        o_data : out std_logic_vector (7 downto 0)
    );
end project_reti_logiche;

Interfaccia della memoria

entity rams_sp_wf is
    port(
        clk : in std_logic;
        we : in std_logic;
        en : in std_logic;
        addr : in std_logic_vector(15 downto 0);
        di : in std_logic_vector(7 downto 0);
        do : out std_logic_vector(7 downto 0)
    );
end rams_sp_wf;

Per maggiori dettagli viene fornito il link alla User Guide di Vivado dalla quale la memoria è stata derivata : https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_3/ug901-vivado-synthesis.pdf

Architettura, approccio e scelte implementative

In questa sezione verrà descritta la FSM1 del progetto seguita da un rapido overview sul codice presentato. Prima però vengono riportate alcune doverose considerazioni riguardanti il linguaggio di programmazione VHDL.

Considerazioni su VHDL

In questo progetto, durante la fase di progettazione e successivamente di sviluppo, non verrà preso mai in considerazione l'utilizzo del costrutto process e di conseguenza di architetture di tipo behavioral . Questa scelta implementativa, che si riflette sia in fase di sintesi che di implementazione, [non è dovuta]{.underline} al fatto che l'autore del progetto creda che l'utilizzo di process sia scorretto in qual si voglia forma o maniera. Si devono riconoscere le potenzialità e le funzionalità implementative/strutturali che ne derivano dall'utilizzo di quest'ultimi ma si deve anche considerare il maggior strato di astrazione portato da questo costrutto rispetto ad architetture dataflow o structural.
È per il motivo sopra citato e per la non diretta corrispondenza tra codice scritto e struttura interna del sintetizzato hardware che in questo progetto sono state scartate implementazioni di tipo behavioral.

Primo design della FSM

Tenendo conto delle considerazioni sopra fatte viene ora presentato un primo design della macchina a stati in grado già di soddisfare ampiamente requisiti di timing sia post sintesi sia post implementazione; viene discussa quest'ultima in quanto alla base del design finale e da considerarsi design ottimale per periodi di clock $clockPeriod \approx [35,100] ns$.

Stati della macchina

Primo design della FSM

con $wc$ definito come numero di parole ancora da codificare.

::: description stato della macchina iniziale dove questa attende che il segnale i_start venga portato alto; una volta che ciò accade in questo stato vengono anche settati o_en = ’1’ e o_address = 0 in modo tale da rendere il modulo pronto a ricevere il numero di parole dalla ram. Questo coincide anche con lo stato di reset della FSM.

stato della macchina dove viene settato il numero di parole da codificare.

stato della macchina adibito alla lettura della prossima parola da codificare. In particolare in questo stato vengono settati i valori valori di o_en = ’1’ e o_address = 1 in modo tale da leggere la parola da codificare in questo ciclo della FSM

serie di 8 stati della macchina utilizzati per l'effettiva codifica della parola. Questi servono in particolare a ciclare sul singolo bit della parola considerata, oltre a contribuire alla sincronizzazione di alcuni segnali necessari al funzionamento del componente(descritto in maniera dettagliata più avanti). Espandiamo specificatamente:

  • $p_0$ : in questo stato viene anche letta la parola richiesta precedentemente nello stato $r$.

  • $p_3$, $p_4$ : in questi stati vengono settati o_en = ’1’ e o_we = ’1’ in modo tale da poter parallelizzare la scrittura della parola in memoria con la sua effettiva computazione.

stato della macchina che si dedica al controllo del numero di parole rimaste da codificare. Se il numero di parole è $\neq 0$ allora la FSM ritornerà alla stato $r$, altrimenti rimarrà in questo stato fintanto che i_start = ’1’ e parallelamente o_done verrà alzato. :::

Design finale della FSM

Come precedentemente scritto, la macchina sopra specificata superava i test bench per periodi di clock $clockPeriod \approx [15,100] ns$ nelle simulazione behavioral e post-sintesi, ma falliva post-implementazione per $clockPeriod <\approx 35 ns$ dove le latenze dell'FPGA erano maggiori.
Una possibile soluzione sarebbe quella di aggiungere altri 2 stati così da poter mitigare i ritardi dovuti alla lettura della memoria. Vengono quindi qui sotto riportate delle semplici, seppur doverose, analisi in termini di tempo e di spazio per poter giustificare il cambiamento delle stuttura della macchina a stati.

Analisi di trade-off spaziale

Considerando il numero di stati $numStati = 12$ e utilizzando la codifica binaria $log_2(numStati) \approx 3.6$ quindi, si utilizzano 4 bit per la rappresentazione di tali stati. È facile verificare che l'aggiunta di 2 stati, quindi $numStati = 14$, non richiede allocamento aggiuntivo di memoria su FPGA.

Analisi di trade-off temporale {#cap:tradeoff_temporale}

Essendo uno di questi 2 stati aggiuntivi eseguito solo una volta in fase di lettura del numero di parole contenuto in ram, esso verrà trascurato perchè asintoticamente irrilevante. Tenendo in considerazione gli stati che vengono eseguiti in loop, facendo riferimento alla figura 2{reference-type="ref" reference="prima_fsm"} gli stati da $r$ a $d$, si ottiene $numStati_{m1} = 10$ e $numStati_{m2} =numStati_{m1} + 1= 11$.
Quindi perchè questa modifica alla FSM sia motivata si deve avere che $$ numStati_{m1} * clockPeriod_{\textit{\text{m1 min}}} > numStati_{m2} * clockPeriod_{m2}

$$ con $clockPeriod_{m1 \space min} = 35 ns$.
Si ottiene che $clockPeriod_{m2} \leq 31.82 ns$, condizione che verrà poi verificata e discussa nella sezione riguardante i risultati sperimentali.

Nuova macchina a Stati

Vengono così aggiunti altri 2 stati :

Wait word count - $w_{wc}$

:

Wait - $w$

:

entrambi adibiti alla mitigazione del ritardo dovuto alla lettura della memoria e alla propagazione di tale segnale in fase di implementazione.

Design finale compatto della FSM finale


Nota : In figuara 3{reference-type="ref" reference="seconda_fsm"} gli stati $p_0,p_1,...,p_7$ sono compressi in un unico stato $p$ al solo fine di alleggerire la notazione della macchina. Essi rimangono quindi separati come mostrato in figura 2{reference-type="ref" reference="prima_fsm"}.

Code overview

L'obbitettivo di questa sezione è quello di mettere in relazione le scelte implementative precedentemente introdotte con l'effettivo codice VHDL del progetto.
Il progetto è composto da 3 principali componenti :

  • controller

  • convolutional_encoder

  • string_manager

Successivamente vengono riportate le interfacce delle entità e una breve spiegazione sulle funzionalità implementate.

controller

È il responsabile per il "comportamento" del componente. Controlla il corretto cycling degli stati ed in modo diretto i segnali di o_en, o_we, o_address e o_done.

entity controller is
    port(
        clock            : in std_logic; --> i_clock
        reset            : in std_logic; --> i_reset
        start            : in std_logic; --> i_start
        data             : in std_logic_vector (7 downto 0); --> i_data
        done             : out std_logic := '-'; --> o_done
        mem_address      : out std_logic_vector(15 downto 0); --> o_address
        mem_enable       : out std_logic; --> o_en
        mem_write        : out std_logic; --> o_we
        u                : out std_logic; --> bit to be encoded
        component_enable : out std_logic := '0'; --> enable signal for other components
        component_reset  : out std_logic := '0' --> reset signal for other components
    );
end controller;

convolutional_encoder

Parte del componente adibita alla codifica di un singolo bit di una parola; implementa il codificatore convoluzionale mostrato in figura 1{reference-type="ref" reference="codificatore_convoluzionale_image"}.

entity convolutional_encoder is 
    port(
        u      : in std_logic; --> u
        clock  : in std_logic; --> i_clock
        reset  : in std_logic; --> component_reset
        enable : in std_logic; --> component_enable
        pk     : out std_logic_vector(1 downto 0) --> encoder's output
    );
end convolutional_encoder;

string_manager

Questo modulo del componente ha il compito di concatenare i 2 bit di output del convolutional_encoder per formare una parola in uscita, da scrivere successivamente in memoria.

entity string_manager is
    port(
    clock  : in std_logic; --> i_clock
    reset  : in std_logic; --> component_reset
    enable : in std_logic; --> component_enable
    bits   : in std_logic_vector(1 downto 0); --> pk
    half_z : out std_logic_vector(7 downto 0) --> o_data
    );
end string_manager;

Schematico del codice

Viene qui riportata un'immagine che mostra i collegamenti fra le varie entità del codice VHDL. La descrizione di tali collegamenti si può ritrovare nell'architettura, di tipo structural, dell'entità project_reti_logiche.

Schematico dei collegamenti tra le varie entità

Risultati sperimentali

In questa sezione verranno discussi tutti i risultati ottenuti attraverso le varie tipologie e i tipi di test utilizzati per assicurare il corretto funzionamento del componente; successivamente vengono riportati alcuni dati sperimentali direttamente ottenuti dal tool di sintesi ed implementazione Vivado. Vengono però prima riportate le dimensioni, in termini di LUT e FF, del componente hardware implementato.

LUT :

: 87

FF :

: 47

Nota : tutti i test eseguiti sono stati eseguiti su FPGA Artix-7 xc7a200tfbg484-1.

Simulazioni

Come precedentemente accennato le simulazioni behavioral e di Post-Synthesis (sia Functional che Timing) ottenevano esiti positivi già utilizzando la FSM in figura 2{reference-type="ref" reference="prima_fsm"} con un range di clock $clockPeriod \approx [15,100] ns$. Tuttavia, per assicurare uno standard minimo di qualità si è comunque preferito testare il componente anche in Post-Implementation. È proprio la neccessità di ottenere un componente in grado di funzionare correttamente in Post-Implementation con periodi di clock $clockPeriod \approx 15 ns$ che ha portato ad una modifica della prima macchina a stati finiti ottenendo il design finale mostrato in figura 3{reference-type="ref" reference="seconda_fsm"}.
Grazie alle simulazioni è stato possibile verificare che il modulo hardware computa correttamente per periodi di clock poco inferiori a $clockPeriod = 15ns$, verificando così un discreto guadagno prestazionale rispetto al primo design presentato (alla sezione 2.3.2{reference-type="ref" reference="cap:tradeoff_temporale"} vengono presentati i calcoli temporali). Va comunque notato che per $clockPeriod > 31.82ns$ il design ottimale rimane ancora il primo discusso.

Simulazione d'esempio

Viene ora commentata una simulazione per mostrare il funzionamento del modulo hardware :

Tipo di simulazione :

: behavioral

TestBench :

: tre_bis.vhdl, fornita dal docente

Periodo di clock :

: $15ns$

Codifica di una parola, simulazione behavioral

La figuara 5{reference-type="ref" reference="behavioral_totale"} mostra l'inizio della testbench e la codifica completa della parola; sulla sinistra sono presenti i segnali facenti parte dell'interfaccia del progetto insieme ad un segnale current_state che rappresenta lo stato corrente della macchina. È stata scelta una simulazione behavioral perchè assente da ritardi dovuti a computazione e/o propagazione, facilitandone così la lettura.
Viene ora spezzata la figura appena sopra riportata per consentirne migliore lettura.

Inizio testbench, lettura parola, inizio computazione e scrittura prima parola codificata

Facendo riferimento alla figura 6{reference-type="ref" reference="behavioral_primi_4"}

::: description La macchina si trova in stato di idle e appena start = ’1’ viene portato o_en = ’1’ per richiedere alla memoria il numero di parole da codificare.

Nella fase di read (r) il componente porta nuovamente o_en = ’1’ preparandosi così per la lettura di una parola.

Il modulo si trova ora nella prima fase di computazione della parola $p_0$. Viene codificato il primo bit della parola precedentemente letta e in parallelo viene aggiornato il valore di o_data.

La macchina si trova nello stato $p_3$; sta quindi codificando il quarto bit e la prima parola è già pronta per essere scritta. Si realizza così un parallelismo tra codifica e scrittura in memoria portando alto i segnali di o_en e o_we. :::

Fine codifica e lettura prossima parola

::: description vedi Marker 4 in riferimento a figuara 6{reference-type="ref" reference="behavioral_primi_4"}

Nello stato $p_7$ il componente ha terminato la codifica dell'intera parola. Similmente a come accade nello stato $p_3$ (Marker 4 in riferimento a figuara 6{reference-type="ref" reference="behavioral_primi_4"}) vi è il parallelismo tra computazione e scrittura in memoria.

Essendo le parole da codificare 2 la FSM ritorna nello stato di read (Marker 2). :::

Testbench

Vengono ora qui discusse le testbench eseguite e la loro potenza di test.

Testbench fornite dal docente {#cap:test_bench_docente}

Questa sezione di testbench comprende in particolare :

  1. tb_esempio_1.vhdl

  2. tb_esempio_2.vhdl

  3. tb_esempio_3.vhdl

  4. tb_seq_max.vhdl

  5. tb_seq_min.vhdl

  6. tb_re_encode.vhdl

  7. tb_reset.vhdl

  8. tb_tre_reset.vhdl

  9. tb_tre_bis.vhdl

Questo set di test è molto vario così come la loro potenza.

::: description sono testbench iniziali per verificare il "basilare" funzionamento del componente hardware2.

testbench utilizzate per verificare il corretto comportamento della macchina in caso di sequenze limite .

testbench che verifica il re-encoding del modulo hardware (senza resettare la macchina) .

testbench che verificano le funzionalità del reset della macchina .

testbench con $clockPeriod = 15ns$ che esegue più encoding in successione. Lo scopo di questo test è verificare il comportamento del modulo con periodi di clock molto bassi. :::

Testbench generate attraverso tool automatico

In questa sezioni vengono ulteriormente distinte :

Entrambe le precedenti testbench hanno come scopo quello di verificare la correttezza del componente sintetizzato mettendo il componente stesso sotto forte stress computazionale.
Inoltre, considerando il secondo tool citato, è stato possibile riutilizzare le testbench della sezione 3.2.1{reference-type="ref" reference="cap:test_bench_docente"} con ram differenti aumentando così anche la loro potenza di test.

Conclusioni

In questo capitolo vengono discussi le limitazioni, possibili miglioramenti e i possibili campi di utilizzo del componente sviluppato.

Limiti del componente hardware

Il modulo hardware non presenta sostanziali problematiche rilevate dall'autore. Soprattutto per $clockPeriod \approx 100ns$, definito come minimo target del progetto, il suddetto componente non presenta alcuna criticità. Viene invece riportato che per $clockPeriod \approx 12ns$ in simulazioni Post-Implementation, Timing il componente non riesce a computare correttamente. Questo è dovuto a causa dei ritardi di computazione e di propagazione del segnale; in particolare, quando il modulo vede alzare i_start (FSM in stato di $idle$) non riesce a richiedere alla memoria il giusto indirizzo prima del cambiamento del nuovo stato. Sebbene questa criticità sia nota, viene scelto di non correggerla in quanto molto lontani dal minimo periodo di clock richiesto.

Possibili miglioramenti - Parallelismo

È subito immediato pensare che la migliore modifica al progetto sia quella di sfruttare le proprietà fisiche del circuito e quindi di implementare un modulo hardware in grado di codificare una parola in un solo ciclo di clock. Questa modifica sarebbe possibile eliminando i flip flop che tengono in memoria gli stati precedenti del codificatore convoluzionale e collegando a cascata 8 codificatori convoluzionali modificati come precedentemente descritto. Il design della macchina a stati di questo componente non sarebbe diversa da quelle riportata in figura 3{reference-type="ref" reference="seconda_fsm"}, con unica eccezione che lo stato $p$ sia effettivamente un unico stato. Considerando che $numStati_{\textit{\text{m loop}}} =11$ e che $numStati_{\textit{\text{m parallela loop}}} = 11 -7 = 4$ si ottiene che : $$\begin{gathered} numStati_{\textit{\text{m loop}}} * 15ns > numStati_{\textit{\text{m parallela loop}}} * clockPeriod_{\textit{\text{m parallela}}}

\end{gathered}$$ Quindi per $clockPeriod_{\textit{\text{m parallela}}} \leq 41.25ns$ si ottiene un componente hardware più performante.
Tale approccio, seppur considerato, non è stato intrapreso in quanto avrebbe "snaturato" il convolutore riportato in figura 1{reference-type="ref" reference="codificatore_convoluzionale_image"}.

Campi di utilizzo del modulo hardware sviluppato

Come già descritto nel capitolo 1, un codificatore convoluzionale trova applicazione in sistemi di telecomunicazione dove l'integrità dell'informazione scambiata è essenziale. Date le dimensioni ridotte dell'implementato trova i maggiori campi d'utilizzo in dispositivi IoT ove non è necessario l'integrazione di una Generic Purpose CPU. Alcuni possibili esempi possone essere :

  • telecamere

  • dispositivi di domotica4

Footnotes

  1. FSM dall'inglese Finite state machine, significa macchina a stati finiti

  2. Per esempio non vengono in alcun modo testati ricodifiche successive o reset della FSM

  3. Nota : il tool non viene rilasciato immediatamente in quanto risiedente nella stessa repository del source code del progetto stesso.

  4. In particolare si intendono quei dispositivi dove la correttezza del dato ricevuto è essenziale

Releases

No releases published

Packages

No packages published