Wie schneide ich eine Ausdrucksbitbreite in Verilog ab?


11

Betrachten Sie einen Ausdruck wie:

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

Dabei ist der Ausgang der Funktion 32 Bit breit und x ist ein Draht mit 16 Bit. Ich möchte nur die niedrigsten 16 Bits des resultierenden xor zuweisen.

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

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

Antworten:


8

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, dass es etwas Schöneres als das geben würde ... Na ja, ich werde nur eine große Anzahl von Kürzungsfunktionen erstellen.
user23106

5

In Ihrem Beispiel schneiden Sie Bits implizit ab.

Durch explizites Abschneiden können häufig die Warnungen in Simulation / Flusen / Synthese entfernt werden.

Eine Möglichkeit, dies inline zu tun, besteht darin, einen Cast-Operator zu verwenden, 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 verworfenen Bits Nullen sind.

Wenn einige der Bits ungleich Null sind, würde ich vorschlagen, immer noch ein Zwischennetz wie @dwikle zu verwenden, das in einer vorherigen Antwort vorgeschlagen wurde , da dadurch klarer wird, dass Sie tatsächlich Bits wegwerfen. Hier ist es wieder als Referenz.

wire[31:0] y;

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

1
Ich denke, das würde nur in SystemVerilog funktionieren. Trotzdem interessant.
Tom Carpenter

@ TomCarpenter, möchten Sie sich auf die Teilmenge von Verilog beschränken, die im IEEE Std 1364-2005 verfügbar ist, anstatt den vollständigen Satz synthetisierbaren Verilog zu verwenden, der in einer der neueren einheitlichen IEEE Std 1800-Versionen 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.
Mattiert

3

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

wire [15:0] not_used ;

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

Ich bin mir nicht sicher, ob dies bei Zuweisungen gültig ist.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.