Files
Progetto-reti-logiche/INFO/PFRL_Specifiche_2526_V2.md
2026-06-12 20:37:03 +02:00

661 lines
12 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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 lAnno 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). LID_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:
● Allindirizzo 0 è memorizzato il numero di task attualmente presenti nella lista.
● A partire dallindirizzo 1 sono memorizzati i task allinterno 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). Allinterno 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 lordinamento che avevano prima dellincremento 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 lordine 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 allindirizzo 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 dallesterno, viene posto a 1 per avviare loperazione
selezionata tramite OP.
● START deve rimanere a 1 fino a quando il modulo non porta il segnale DONE a 1,
indicando che loperazione è 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 allindirizzo 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
lazzeramento è 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 dellordine 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 anchesso unico per tutto il sistema. Tutti i segnali
sono sincroni e devono essere interpretati sul fronte di salita del clock. Lunica eccezione è
RESET che, invece, è asincrono. RESET può essere generato in qualsiasi momento
dellesecuzione.
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
limpossibilità 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 loperazione da dover effettuare sulla
lista di task;
● o_done è il segnale DONE di uscita che comunica la fine dellelaborazione;
● 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 lindirizzo 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 allinterno 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
Lesempio qui di seguito mostra il comportamento a seguito dei segnali di ingresso. Qui di
seguito è presente la situazione della memoria a seguito dellinserimento di diversi task (fase
non mostrata nellesempio). 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.