Domanda

Devo implementare una funzione 4 a 1 in Veriog.L'input è di 4 bit, un numero compreso tra 0 e 15.L'output è un singolo bit, 0 o 1.Ogni input fornisce un output diverso e la mappatura dagli input agli output è nota, ma gli input e gli output stessi non lo sono.Voglio che vcs ottimizzi con successo il codice e che sia anche il più breve/ordinato possibile.La mia soluzione finora:

wire [3:0] a;
wire b;
wire [15:0] c;

assign c = 16'b0100110010111010; //for example but could be any constant
assign b = c[a];

Dover dichiarare c è brutto e non so se vcs riconoscerà la K-map lì.Funzionerà altrettanto bene di una dichiarazione di caso o di un incarico in forma normale congiuntiva?

È stato utile?

Soluzione

Quello che hai va bene.Anche una dichiarazione del caso funzionerebbe altrettanto bene.È solo questione di quanto desideri essere espressivo.

La tua soluzione, l'indicizzazione, funziona bene se le codifiche selezionate non hanno alcun significato speciale (ad esempio un selettore di indirizzi di memoria).Se le codifiche select hanno un significato semantico speciale per te che sei il progettista (e non ce ne sono molte), allora usa un'istruzione case ed enumerazioni.

Per quanto riguarda la sintesi, non importa quale usi.Qualsiasi strumento di sintesi decente produrrà lo stesso risultato.

Altri suggerimenti

Sono totalmente d'accordo con Dallas.Usa un'istruzione case: rende più chiaro il tuo intento.Lo strumento di sintesi lo costruirà come una tabella di ricerca (se è parallela) e ottimizzerà tutto ciò che può.

Inoltre, non mi preoccuperei così tanto di mantenere breve il codice RTL.Vorrei prima fare chiarezza.Gli strumenti di sintesi sono più intelligenti di quanto pensi...

La mia preferenza, se ha senso per il tuo problema, è per un'istruzione case che fa uso di enumerazioni o `defines.Tutto per facilitare la revisione, la manutenzione e la verifica del codice.

Per cose come questa, la chiarezza RTL supera di gran lunga tutto.SystemVerilog ha speciali direttive sempre bloccate per rendere chiaro quando il blocco deve sintetizzarsi in logica combinatoria, latch o flop (e il tuo strumento di sintesi dovrebbe generare un errore se hai scritto RTL che è in conflitto con quello (ad es.escludendo tutti i segnali nell'elenco di sensibilità di un blocco sempre).Tieni inoltre presente che lo strumento probabilmente sostituirà qualsiasi codifica tu abbia con la codifica più efficiente in termini di hardware (quella che riduce al minimo l'area del tuo progetto totale), a meno che la codifica stessa non si propaghi ai pin del tuo modulo di livello superiore.

Questo consiglio vale anche in generale.Rendi il tuo codice facile da comprendere per gli esseri umani e probabilmente sarà più comprensibile anche per lo strumento di sintesi, che gli consente di portare letteralmente più efficacemente migliaia di anni-uomo di ricerca sugli algoritmi da sostenere sul tuo RTL.

Puoi anche codificarlo utilizzando gli operatori ternari, se preferisci, ma preferirei qualcosa del tipo:

always_comb //or "always @*" if you don't have an SV-enabled tool flow
begin 
  case(a)
  begin
    4'b0000: b = 1'b0;
    4'b0001: b = 1'b1;
    ...
    4'b1111: b = 1'b0;
    //If you don't specify a "default" clause, your synthesis tool
    //Should scream at you if you didn't specify all cases,
    //Which is a good thing (tm)
  endcase //a
end //always

Apparentemente sto usando uno strumento di sintesi scadente.:-) Ho appena sintetizzato entrambe le versioni (solo il modulo utilizzando un modello basato su fan-out per ritardi dei cavi) e la versione di indicizzazione della domanda ha fornito risultati di tempistica e area migliori rispetto alle dichiarazioni del caso.Utilizzando Synopsys DC Z-2007.03-SP.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top