Passa al tema normale
Discussioni su argomenti di Informatica

Regole del forum

Consulta il nostro regolamento e la guida per scrivere le formule
Rispondi al messaggio

[C++] Compilatori per linguaggi di descrizione dell'hardware

01/07/2019, 18:08

Ciao a tutti,

Sono uno studente di Ingegneria Elettronica, e nel piano di studi ho un esame di Programmazione a Oggetti, in cui abbiamo studiato in modo abbastanza approfondito il C++ e alcune strutture dati e algoritmi importanti (alberi, grafi, liste, etc.).

La prova consiste nella presentazione di un progetto, che quest'anno verte sulla creazione di un simulatore di circuiti logici, basato su una versione (molto) semplificata del Verilog. In sostanza, il nostro programma riceve in input dei file in cui sono descritti dei circuiti digitali composti da porte logiche e flip-flop di tipo D, più un altro file che contiene gli input da fornire ai circuiti stessi. Il programma deve restituire un altro file con i corrispondenti output. E' prevista anche la possibilità di definire circuiti composti; ossia possiamo descrivere un circuito X in un file, e poi includere delle istanze di X in un altro circuito Y, descritto in un file diverso.

Sto riscontrando un bel po' di difficoltà nell'affrontare questo progetto, specialmente per quanto riguarda la definizione dei circuiti composti e la traduzione file Verilog --> circuito.
Ho trovato in rete tantissimi libri che spiegano come sono fatti i compilatori di linguaggi di programmazione, ma nessuno sui compilatori di linguaggi HDL.
Se ne conoscete, o se disponete di qualsiasi tipo di riferimento che potrebbe aiutarmi a lavorare su questo progetto, vi prego di segnalarmelo.

Grazie mille in anticipo :-)

Re: [C++] Compilatori per linguaggi di descrizione dell'hardware

02/07/2019, 11:08

A me non sembra che il tuo lavoro sia così diverso da fare qualcosa come:

Dati
\(\displaystyle f(x) = x^2 + 3 \)
\(\displaystyle g(x) = e^{f(x)} + \bigl[f(x)\bigr]^3 \)
come testo ritornare il valore esatto di \(g(3)\).

Si tratta di costruire una struttura ad albero del circuito in cui i figli di un nodo sono sottocircuiti.

Re: [C++] Compilatori per linguaggi di descrizione dell'hardware

02/07/2019, 13:26

vict85 ha scritto:A me non sembra che il tuo lavoro sia così diverso da fare qualcosa come:

Dati
\(\displaystyle f(x) = x^2 + 3 \)
\(\displaystyle g(x) = e^{f(x)} + \bigl[f(x)\bigr]^3 \)
come testo ritornare il valore esatto di \(g(3)\).

Si tratta di costruire una struttura ad albero del circuito in cui i figli di un nodo sono sottocircuiti.


Grazie per la risposta.

L'idea di usare gli alberi l'ho già implementata. Ho creato una classe "Nodo" da cui ho derivato altre due classi "PortaLogica" e "FlipFlop"; ho definito anche un'altra classe "Circuito" che contiene una sorta di "expression tree" che rappresenta il circuito(dico una sorta perché ci è richiesto anche di poter generare circuiti sequenziali dotati di feedback, e a questo punto diventano grafi invece che alberi), di cui valuto gli output con una funzione ricorsiva.
Quello che non riesco a fare è riutlizzare un circuito già definito in un altro. Non capisco come fare a "ricopiare" il grafo di un circuito X e inserirlo nel grafo di un circuito Y. Essendo poi i circuiti tutti definiti in file separati, non saprei proprio come gestirli. Immagino che dovrei implementare una sorta di linker.

Ora, anche assumendo che io riesca a superare questo ostacolo, sono bloccato sulla parte di traduzione del codice Verilog. Francamente non ho idea di come analizzare un'espressione come $$x = NOT(a AND (b OR c))$$ e ricavarne il grafo.

Re: [C++] Compilatori per linguaggi di descrizione dell'hardware

02/07/2019, 13:32

Per quanto riguarda il parsing, non ci sono molte differenze rispetto ad altri linguaggi di programmazione. Devi costruire una gerarchia di classi che rappresentano i principali costrutti del tuo linguaggio. Otterrai in questo modo un grafo sul quale fare ulteriori elaborazioni. Le fasi successive nella implementazione di un compilatore non sono invece particolarmente utili nel tuo caso.

Non conosco molto verilog, ma di solito ogni componente è rappresentato da un qualche tipo di oggetto con determinati input e output. Un circuito sarà semplicemente un componente che può a sua volta essere caricato in un altro. Per calcolare gli output dalla tua gerarchia di oggetti farei poi probabilmente uso di qualcosa tipo il visitor pattern.

Re: [C++] Compilatori per linguaggi di descrizione dell'hardware

03/07/2019, 22:11

apatriarca ha scritto:Per quanto riguarda il parsing, non ci sono molte differenze rispetto ad altri linguaggi di programmazione. Devi costruire una gerarchia di classi che rappresentano i principali costrutti del tuo linguaggio. Otterrai in questo modo un grafo sul quale fare ulteriori elaborazioni. Le fasi successive nella implementazione di un compilatore non sono invece particolarmente utili nel tuo caso.


Innanzitutto grazie per la risposta. Ho provato a sfogliare un libro sui compilatori, ma non credo sia fattibile studiare i capitoli relativi al parsing a quel livello di approfondimento, considerato il tempo che ho. Forse chiedo troppo, ma per caso conosci dei riferimenti online che spieghino queste cose in maniera un po' più concisa e pratica?

apatriarca ha scritto:Un circuito sarà semplicemente un componente che può a sua volta essere caricato in un altro.


Io ho rappresentato i circuiti come dei grafi. In particolare, i circuiti combinatori sono degli expression trees, di cui calcolo gli output con una funzione ricorsiva. Come potrei inserire un circuito in un altro circuito, cioè un copiare un grafo e collegarlo ad un altro? Inizialmente ho provato a inserire nella mia classe Circuito un vettore di puntatori a Circuito, ma non ha funzionato un granché :?

Mi rendo conto che non è facile dare una mano senza conoscere i dettagli della implementazione, ma qualsiasi indicazione, anche vaga, può essermi d'aiuto.

Re: [C++] Compilatori per linguaggi di descrizione dell'hardware

03/07/2019, 23:04

Senza vedere quello che stai cercando di fare è difficile essere precisi. Ma in linea di massima è necessario distinguere tra la definizione di un circuito, in cui elenchi le porte e memorizzi l'albero, e le istanze all'interno degli altri circuiti. Quando leggi un circuito in un file ne memorizzerai la definizione in un qualche dizionario e quando troverai invece una istanza creerai un nodo nell'expression tree che farà riferimento alla tua definizione.

Una risorsa online che potresti provare a sfogliare è Crafting Interpreters. Forse è un po' lungo, ma contiene per esempio un capitolo sulla implementazione di classi nel linguaggio che potrebbe esserti utile. Si tratta inoltre di una risorsa più pratica che teorica. Ci sono comunque tantissime risorse online sui compilatori.
Rispondi al messaggio


Skuola.net News è una testata giornalistica iscritta al Registro degli Operatori della Comunicazione.
Registrazione: n° 20792 del 23/12/2010.
©2000— Skuola Network s.r.l. Tutti i diritti riservati. — P.I. 10404470014.