661 lines
12 KiB
Markdown
661 lines
12 KiB
Markdown
Progetto di Reti Logiche
|
||
|
||
Prof. Fornaciari, Prof. Palermo e Prof. Salice
|
||
Anno Accademico 2025 - 2026
|
||
|
||
SPECIFICA per lo svolgimento del progetto
|
||
Revisione del 24 Febbraio 2026
|
||
|
||
Descrizione generale
|
||
La specifica della “Prova Finale (Progetto di Reti Logiche)” per l’Anno Accademico
|
||
2025/2026 chiede di implementare un modulo HW (descritto in VHDL) che si interfacci con
|
||
una memoria e che rispetti le indicazioni riportate nella seguente specifica.
|
||
|
||
Si richiede di progettare e implementare in VHDL un modulo hardware che gestisce una lista
|
||
ordinata di task memorizzati in una memoria esterna. Ogni task è rappresentato da una
|
||
coppia di campi: ID_TASK (6 bit) e PRIORITY (2 bit). Ad esempio, 00100111 indica il task
|
||
con ID 001001 che ha priorità 11. Le priorità vanno da 0 (più alta) a 3 (più bassa). Non
|
||
possono esistere due task con lo stesso ID_TASK (questo implica che non possono esistere
|
||
più di 63 task nella lista). L’ID_TASK è sempre un numero positivo e 0 rappresenta una
|
||
condizione di errore (lista vuota).
|
||
|
||
La lista dei task è memorizzata in una memoria con la seguente struttura:
|
||
|
||
● All’indirizzo 0 è memorizzato il numero di task attualmente presenti nella lista.
|
||
● A partire dall’indirizzo 1 sono memorizzati i task all’interno di un byte di memoria
|
||
(ID_TASK & PRIORITY), che devono essere sempre mantenuti ordinati in base alla
|
||
priorità (priorità più bassa numericamente = più alta gerarchicamente, e quindi prima
|
||
nella lista). All’interno del byte, ID_TASK occupa i 6 bit più alti e PRIORITY i 2 bit più
|
||
bassi. Ad esempio, 0x00001100 è il task con ID_TASK 3 e PRIORITY 0.
|
||
|
||
Il modulo deve supportare quattro operazioni, selezionate tramite un ingresso di controllo a 2
|
||
bit denominato OP:
|
||
|
||
● OP = 00: decrementa la priorità di tutti i task presenti nella lista. Ogni indicatore di
|
||
priorità deve essere incrementato di 1, senza superare il valore numerico massimo (3
|
||
- priorità più bassa). Il valore di priorità satura a 3 (priorità minima). Tutti i task
|
||
mantengono l’ordinamento che avevano prima dell’incremento del valore di priorità.
|
||
In particolare, la lista dei task a priorità 3 vedrà prima tutti i task che avevano priorità
|
||
2 e poi quelli che già erano a priorità 3 (in pratica sarà sufficiente modificare i valori di
|
||
priorità senza alcun riordino).
|
||
|
||
● OP = 01: Rimuove dalla lista il primo task (indirizzo 1). Tutti i task successivi devono
|
||
essere spostati di una posizione, il numero di task deve essere decrementato, e il
|
||
numero del task estratto deve essere fornito in uscita dal modulo. Il primo task della
|
||
lista potrebbe avere una priorità qualunque (0, 1, 2 o 3). In caso di lista vuota, deve
|
||
essere fornito in uscita il valore di ID_TASK 0 (0x000000) . Il valore ID_TASK deve
|
||
essere valido quando DONE viene portato a 1.
|
||
|
||
● OP = 10: Aggiunge un nuovo task alla lista, inserendolo in coda ai task a pari priorità,
|
||
preservando l’ordine di tutti gli altri task. Se la lista è vuota, il task deve essere
|
||
inserito in prima posizione.
|
||
|
||
● OP = 11: Svuota completamente la lista. Il valore in memoria all’indirizzo 0 deve
|
||
essere posto a zero; il contenuto degli altri indirizzi può essere ignorato (quello che è
|
||
stato scritto in passato riamane invariato) o resettato (tutti i valori sono posti a zero).
|
||
|
||
Il modulo utilizza un protocollo di hand-shake START-DONE per la sincronizzazione con la
|
||
logica esterna. Il comportamento richiesto è il seguente:
|
||
|
||
●
|
||
|
||
Il segnale START, generato dall’esterno, viene posto a 1 per avviare l’operazione
|
||
selezionata tramite OP.
|
||
|
||
● START deve rimanere a 1 fino a quando il modulo non porta il segnale DONE a 1,
|
||
|
||
indicando che l’operazione è stata completata.
|
||
|
||
● Quando DONE è a 1, la logica esterna deve riportare START a 0.
|
||
● Quando START torna a 0, il modulo può riportare DONE a 0 e prepararsi a ricevere
|
||
|
||
una nuova operazione.
|
||
|
||
● Una nuova operazione può essere avviata solo quando DONE è a 0.
|
||
|
||
Dopo che il modulo viene resettato (quindi subito dopo la transizione RESET 1 -> 0), esso
|
||
deve comportarsi come segue:
|
||
|
||
● Dopo un reset, la lista deve essere considerata vuota. Il modulo deve quindi scrivere
|
||
|
||
il valore zero all’indirizzo 0 della memoria.
|
||
|
||
● Durante questa fase di inizializzazione, il segnale DONE deve essere mantenuto a 1,
|
||
indicando che il modulo non è ancora pronto a ricevere operazioni, e solo dopo che
|
||
l’azzeramento è stato effettuato, il modulo può riportare DONE a 0 e rendersi
|
||
disponibile a nuove operazioni.
|
||
|
||
Il modulo deve garantire:
|
||
|
||
Il corretto aggiornamento della memoria in seguito a ogni operazione.
|
||
Il mantenimento dell’ordine dei task nella lista.
|
||
|
||
●
|
||
●
|
||
● La gestione appropriata dei casi limite, ad esempio lista vuota.
|
||
●
|
||
|
||
Il rispetto del protocollo START-DONE come descritto.
|
||
|
||
Si precisa che
|
||
la presente specifica descrive un comportamento completamente
|
||
deterministico: a parità di sequenze di ingresso, le uscite generate e il contenuto della
|
||
memoria nella parte valida (lista dei task) risultano invariati. Qualsiasi eventuale scenario
|
||
che presenti ambiguità o comportamenti non univocamente determinati dovrà essere
|
||
identificato e prontamente segnalato.
|
||
|
||
Interfaccia del Componente
|
||
Il modulo da implementare ha 4 ingressi primari, uno ad 1 bit (i_start), uno a 6 bit (i_task_id),
|
||
uno a 2 bit (i_task_priority) e uno da 2 bit (i_op), e due uscite primarie, una da 1 bit (o_done)
|
||
e una da 6 bit (o_task_id). Inoltre, il modulo ha un segnale di clock CLK, unico per tutto il
|
||
sistema e un segnale di reset RESET anch’esso unico per tutto il sistema. Tutti i segnali
|
||
sono sincroni e devono essere interpretati sul fronte di salita del clock. L’unica eccezione è
|
||
RESET che, invece, è asincrono. RESET può essere generato in qualsiasi momento
|
||
dell’esecuzione.
|
||
|
||
Il componente da descrivere deve avere la seguente interfaccia.
|
||
|
||
entity project_reti_logiche is
|
||
|
||
port (
|
||
|
||
i_clk : in std_logic;
|
||
|
||
i_rst : in std_logic;
|
||
|
||
i_start
|
||
|
||
: in std_logic;
|
||
|
||
i_task_id
|
||
|
||
: in std_logic_vector(5 downto 0);
|
||
|
||
i_task_priority : in std_logic_vector(1 downto 0);
|
||
|
||
i_op : in std_logic_vector(1 downto 0);
|
||
|
||
o_done : out std_logic;
|
||
|
||
o_task_id : out std_logic_vector(5 downto 0);
|
||
|
||
o_mem_addr : out std_logic_vector(15 downto 0);
|
||
|
||
i_mem_data : in std_logic_vector(7 downto 0);
|
||
|
||
o_mem_data : out std_logic_vector(7 downto 0);
|
||
|
||
o_mem_we : out std_logic;
|
||
|
||
o_mem_en : out std_logic
|
||
|
||
);
|
||
|
||
end project_reti_logiche;
|
||
|
||
In particolare:
|
||
|
||
●
|
||
|
||
●
|
||
●
|
||
|
||
●
|
||
●
|
||
|
||
il nome del modulo deve essere project_reti_logiche e deve essere
|
||
presente una sola architettura per ogni entità; la violazione di queste
|
||
indicazioni comporta
|
||
il Test Bench e una
|
||
l’impossibilità di eseguire
|
||
conseguente valutazione di zero;
|
||
i_clk è il segnale di CLOCK in ingresso generato dal Test Bench;
|
||
i_rst è il segnale di RESET che inizializza la macchina pronta per ricevere il
|
||
primo segnale di START;
|
||
i_start è il segnale di START generato dal Test Bench;
|
||
i_task_id è il vettore di bit rappresentante il ID_TASK generato dal Test
|
||
Bench;
|
||
|
||
●
|
||
|
||
●
|
||
|
||
i_task_priority è il vettore di bit rappresentante il PRIORITY generato dal Test
|
||
Bench;
|
||
i_op è il vettore di 2 bit rappresentante l’operazione da dover effettuare sulla
|
||
lista di task;
|
||
|
||
● o_done è il segnale DONE di uscita che comunica la fine dell’elaborazione;
|
||
● o_task_id è il vettore di bit rappresentante il ID_TASK del task a priorità più
|
||
|
||
alta estratto dalla memoria;
|
||
|
||
● o_mem_addr è il segnale (vettore) di uscita che manda l’indirizzo alla
|
||
|
||
●
|
||
|
||
memoria;
|
||
i_mem_data è il segnale (vettore) che arriva dalla memoria e contiene il dato
|
||
in seguito ad una richiesta di lettura;
|
||
|
||
● o_mem_data è il segnale (vettore) che va verso la memoria e contiene il dato
|
||
|
||
che verrà successivamente scritto;
|
||
|
||
● o_mem_en è il segnale di ENABLE da dover mandare alla memoria per poter
|
||
|
||
comunicare (sia in lettura che in scrittura);
|
||
|
||
● o_mem_we è il segnale di WRITE ENABLE da dover mandare alla memoria
|
||
|
||
(=1) per poter scriverci. Per leggere da memoria, esso deve essere 0.
|
||
|
||
APPENDICE: Descrizione Memoria
|
||
NOTA: La memoria è già istanziata all’interno del Test Bench e non va sintetizzata
|
||
|
||
La memoria e il suo protocollo può essere estratto dalla seguente descrizione VHDL che fa
|
||
parte del test bench e che è derivata dalla User guide di VIVADO disponibile al seguente
|
||
link:
|
||
https://www.xilinx.com/support/documentation/sw_manuals/xilinx2017_3/ug901-vivado-synth
|
||
esis.pdf
|
||
|
||
-- Single-Port Block RAM Write-First Mode (recommended template)
|
||
--
|
||
-- File: rams_02.vhd
|
||
--
|
||
library ieee;
|
||
use ieee.std_logic_1164.all;
|
||
use ieee.std_logic_unsigned.all;
|
||
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;
|
||
|
||
architecture syn of rams_sp_wf is
|
||
type ram_type is array (65535 downto 0) of std_logic_vector(7 downto 0);
|
||
signal RAM : ram_type;
|
||
begin
|
||
process(clk)
|
||
|
||
begin
|
||
if clk'event and clk = '1' then
|
||
if en = '1' then
|
||
if we = '1' then
|
||
|
||
RAM(conv_integer(addr)) <= di;
|
||
do
|
||
|
||
<= di after 2 ns;
|
||
|
||
else
|
||
|
||
do <= RAM(conv_integer(addr)) after 2 ns;
|
||
|
||
end if;
|
||
end if;
|
||
end if;
|
||
end process;
|
||
end syn;
|
||
|
||
ESEMPIO
|
||
L’esempio qui di seguito mostra il comportamento a seguito dei segnali di ingresso. Qui di
|
||
seguito è presente la situazione della memoria a seguito dell’inserimento di diversi task (fase
|
||
non mostrata nell’esempio). I valori non espliciti sono valori di memoria che non vengono
|
||
considerati per il normale funzionamento.
|
||
|
||
SITUAZIONE INIZIALE (6 task già in tabella)
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000110
|
||
|
||
0x01000000
|
||
|
||
0x01011000
|
||
|
||
0x01011100
|
||
|
||
0x01010101
|
||
|
||
0x01110010
|
||
|
||
0x00010011
|
||
|
||
16
|
||
|
||
22
|
||
|
||
23
|
||
|
||
21
|
||
|
||
28
|
||
|
||
4
|
||
|
||
0
|
||
|
||
0
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
4
|
||
|
||
5
|
||
|
||
6
|
||
|
||
7
|
||
|
||
OPERAZIONE: 00 (incremento valore di priorità)
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000110
|
||
|
||
0x01000001
|
||
|
||
0x01011001
|
||
|
||
0x01011101
|
||
|
||
0x01010110
|
||
|
||
0x01110011
|
||
|
||
0x00010011
|
||
|
||
16
|
||
|
||
22
|
||
|
||
23
|
||
|
||
21
|
||
|
||
28
|
||
|
||
4
|
||
|
||
1
|
||
|
||
1
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
3
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
4
|
||
|
||
5
|
||
|
||
6
|
||
|
||
7
|
||
|
||
OPERAZIONE: 10 (aggiunge un task) - ID_TASK: 19 - PRIORITY: 2
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000111
|
||
|
||
0x01000001
|
||
|
||
0x01011001
|
||
|
||
0x01011101
|
||
|
||
0x01010110
|
||
|
||
0x01001110
|
||
|
||
0x01110011
|
||
|
||
0x00010011
|
||
|
||
16
|
||
|
||
22
|
||
|
||
23
|
||
|
||
21
|
||
|
||
19
|
||
|
||
28
|
||
|
||
4
|
||
|
||
1
|
||
|
||
1
|
||
|
||
1
|
||
|
||
2
|
||
|
||
2
|
||
|
||
3
|
||
|
||
3
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
4
|
||
|
||
5
|
||
|
||
6
|
||
|
||
7
|
||
|
||
8
|
||
|
||
OPERAZIONE: 01 (rimuove il primo task)
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000110
|
||
|
||
0x01011001
|
||
|
||
0x01011101
|
||
|
||
0x01010110
|
||
|
||
0x01001110
|
||
|
||
0x01110011
|
||
|
||
0x00010011
|
||
|
||
22
|
||
|
||
23
|
||
|
||
21
|
||
|
||
19
|
||
|
||
28
|
||
|
||
4
|
||
|
||
1
|
||
|
||
1
|
||
|
||
2
|
||
|
||
2
|
||
|
||
3
|
||
|
||
3
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
4
|
||
|
||
5
|
||
|
||
6
|
||
|
||
7
|
||
|
||
OPERAZIONE: 11 (svuota la lista)
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000000
|
||
|
||
0
|
||
|
||
1
|
||
|
||
OPERAZIONE: 10 (aggiunge un task) - ID_TASK: 31 - PRIORITY: 3
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000001
|
||
|
||
0x01111111
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
OPERAZIONE: 10 (aggiunge un task) - ID_TASK: 15 - PRIORITY: 0
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0x00000010
|
||
|
||
0x00111100
|
||
|
||
0x01111111
|
||
|
||
15
|
||
|
||
31
|
||
|
||
0
|
||
|
||
3
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
OPERAZIONE: 10 (aggiunge un task) - ID_TASK: 20 - PRIORITY: 0
|
||
|
||
MEMORIA
|
||
|
||
INDIRIZZO
|
||
|
||
VALORE
|
||
|
||
ID_TASK PRIORITY
|
||
|
||
0
|
||
|
||
1
|
||
|
||
2
|
||
|
||
3
|
||
|
||
0x000000011
|
||
|
||
0x00111100
|
||
|
||
0x01010000
|
||
|
||
0x01111111
|
||
|
||
15
|
||
|
||
20
|
||
|
||
31
|
||
|
||
0
|
||
|
||
0
|
||
|
||
3
|
||
|
||
Progetto di Reti Logiche
|
||
|
||
Prof. Fornaciari, Prof. Palermo e Prof. Salice
|
||
Anno Accademico 2025 - 2026
|
||
|
||
NOTE DI AGGIORNAMENTO DELLA SPECIFICA
|
||
|
||
In questa pagina potete trovare le modifiche fatte alla specifica del progetto dal suo primo rilascio.
|
||
Tutti i cambiamenti con data annessa saranno riportati qui sotto e sono mantenuti in rosso nel testo.
|
||
|
||
Errata Corrige:
|
||
|
||
- Aggiornamento 24.02.2026:
|
||
|
||
-
|
||
|
||
Il numero massimo di task nella lista non è 31 come nella versione originale ma 63.
|
||
Questo è derivato dal fatto che il numero di bit per il task_id è 6.
|
||
|