Jak obciąć szerokość bitu wyrażenia w Verilog?

11

Rozważ wyrażenie takie jak:

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

gdzie wyjście func ma szerokość 32 bitów, a x jest drutem o długości 16 bitów. Chcę przypisać tylko najniższe 16 bitów wynikowego xor.

Wiem, że powyższy kod już to robi, ale generuje również ostrzeżenie. „Oczywiste” podejście nie działa:

assign x = (func(A) ^ func(B))[15:0]; // error: '[' is unexpected
użytkownik23106
źródło

Odpowiedzi:

8

Możesz użyć innej zmiennej, choć nie jest to szczególnie eleganckie.

wire[31:0] y;

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

Lepszym podejściem byłoby użycie funkcji.

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));
dwikle
źródło
Miałem nadzieję, że będzie coś ładniejszego ... Cóż, po prostu utworzę dużą liczbę obcinających funkcji.
user23106,
5

W twoim przykładzie domyślnie obcinasz bity.

Wyraźne obcięcie może często usunąć ostrzeżenia w symulacji / kłaczkach / syntezie.

Jednym ze sposobów na zrobienie tego w linii jest użycie operatora rzutowania, np .:

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

To podejście może mieć sens, jeśli z kontekstu wynika, że ​​wszystkie upuszczane bity to 0.

Jeśli niektóre bity mogą być niezerowe, sugerowałbym używanie sieci pośredniej, takiej jak @dwikle sugerowanej w poprzedniej odpowiedzi , ponieważ to wyjaśnia, że ​​faktycznie wyrzucasz bity. Tutaj jest ponownie w celach informacyjnych.

wire[31:0] y;

assign y = func(A) ^ func(B);
assign x = y[15:0];
matowo
źródło
1
Myślę, że to działałoby tylko w SystemVerilog. Ciekawe nie mniej.
Tom Carpenter
@TomCarpenter, czy chcesz ograniczyć się do podzbioru Verilog dostępnego w IEEE Std 1364-2005, zamiast korzystać z pełnego zestawu syntezowalnego verilog dostępnego w jednej z nowszych zunifikowanych wersji IEEE Std 1800? Możesz powiedzieć Verilog-2005 lub coś do wyjaśnienia, ponieważ standard Verilog został włączony do ujednoliconego standardu SystemVerilog w 2009 roku.
Mattgately
3

Myślę, że może to pomóc w odliczaniu linii.

wire [15:0] not_used ;

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

Nie jestem jednak pewien, czy dotyczy to przypisań.

pre_randomize
źródło