Verilog cambia la dimensione del lato destro
Ho un modulo di base come segue per dimostrare qualcosa.
module tb();
reg [2:0] U;
reg [2:0] T;
reg [2:0] C;
reg E;
initial begin
U = 5;
T = 3;
{E, C} = U + ~T + 1'b1;
#1000;
end
endmodule
Quello che mi aspetto è che E sia 1, perché;
U
è 101
T
è 011
ed U + ~T + 001
è,
101
100
001
+______
= 1010
Quindi, C ottiene la parte 010 ed E ottiene 1. Questo è il comportamento previsto, tuttavia, ottengo C uguale ma E come 0. Penso che verilog stia aumentando le dimensioni delle variabili RHS a 4 bit perché il lato sinistro è di 4 bit ( 1 + 3). Tuttavia, per T, aggiunge lo 0 iniziale prima di completare T, quindi T diventa 0011 e il suo complemento risulta essere 1100, invece di 0100, versione a 4 bit del complemento T.
E questo porta a
0101
1100
0001
+______
= 10010
Il che fa sì che E sia 0 come visto.
Non capisco perché sia così e non sono riuscito a trovare un modo per far sì che il completamento avvenga prima di aggiungere uno zero iniziale.
Se invece faccio quanto segue, funziona bene e E ottiene 1:
U = 5;
T = 3;
T = ~T;
{E, C} = U + T + 1'b1;
Ciò conferma che il mio sospetto è giusto. Quindi, ho una soluzione del genere, sì. Tuttavia, non ne sono davvero soddisfatto, penso che dovrebbe esserci un modo per prevenire quel comportamento.
Qualsiasi aiuto sarebbe apprezzato.
Risposte
Quando si dispone di operandi composti da una combinazione di larghezze diverse, Verilog dispone di regole per il dimensionamento di ciascun operando alla larghezza dell'operando più grande in base al contesto dell'espressione. Hai notato correttamente che l'LHS è di 4 bit, gli operandi sull'RHS vengono estesi a 4 bit. Questo accade prima di applicare l'operazione.
Puoi risolvere questo problema sfruttando il fatto che gli operandi di una concatenazione sono contesti autodeterminati:
{E, C} = U + {~T} + 1'b1;
Ora la larghezza di ~T
è determinata esclusivamente dalla larghezza di T
.