Wie kürze ich die Bitbreite eines Ausdrucks in Verilog?

Betrachten Sie einen Ausdruck wie:

assign x = func(A) ^ func(B);

wobei die Ausgabe der Funktion 32 Bit breit ist und x eine Leitung von 16 Bit ist. Ich möchte nur die niedrigsten 16 Bits des resultierenden xor zuweisen.

Ich weiß, dass der obige Code das bereits tut, aber es generiert auch eine Warnung. Der "offensichtliche" Ansatz funktioniert nicht:

assign x = (func(A) ^ func(B))[15:0]; // error: '[' is unexpected

Antworten (3)

Sie können eine andere Variable verwenden, obwohl dies nicht besonders elegant ist.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];

Ein besserer Ansatz wäre die Verwendung einer Funktion.

function [15:0] trunc_32_to_16(input [31:0] val32);
  trunc_32_to_16 = val32[15:0];
endfunction

assign x = trunc_32_to_16(func(A) ^ func(B));
Ich hatte gehofft, es gäbe etwas Schöneres als das ... Na ja, ich werde einfach eine große Anzahl von Abschneidefunktionen erstellen.

In Ihrem Beispiel schneiden Sie implizit Bits ab.

Die Kürzung explizit zu machen, kann oft die Warnungen in Simulation/Lint/Synthese entfernen.

Eine Möglichkeit, dies inline zu tun, ist die Verwendung eines Cast-Operators, z.

typedef logic [15:0] HALF_WORD;
assign x = HALF_WORD'((func(A) ^ func(B));

Dieser Ansatz kann sinnvoll sein, wenn aus dem Kontext ersichtlich ist, dass alle weggelassenen Bits Nullen sind.

Wenn einige der Bits möglicherweise ungleich Null sind, würde ich vorschlagen, weiterhin ein Zwischennetz zu verwenden, wie @dwikle in einer vorherigen Antwort vorgeschlagen hat, da dies deutlicher macht, dass Sie tatsächlich Bits wegwerfen. Hier nochmal zum Nachschlagen.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];
Ich denke, das würde nur in SystemVerilog funktionieren. Nichtsdestotrotz interessant.
@TomCarpenter, möchten Sie sich auf die Teilmenge von Verilog beschränken, die in IEEE Std 1364-2005 verfügbar ist, anstatt den vollständigen Satz von synthetisierbarem Verilog zu verwenden, der in einer der neueren einheitlichen IEEE Std 1800-Revisionen verfügbar ist? Vielleicht möchten Sie Verilog-2005 oder etwas zur Klarstellung sagen, da der Verilog-Standard 2009 in den einheitlichen SystemVerilog-Standard aufgenommen wurde.

Ich denke, dass dies dazu beitragen könnte, den Zeilenzähler niedrig zu halten.

wire [15:0] not_used ;

assign {not_used, x} = (func(A) ^ func(B));

Bin mir aber nicht sicher, ob das bei Zuweisungen gilt.