Verilog zmienia rozmiar prawej strony

Jan 14 2021

Mam następujący moduł podstawowy, aby coś zademonstrować.

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

Oczekuję, że E będzie równe 1, ponieważ;

U jest 101

T jest 011

i U + ~T + 001jest,

   101
   100
   001
+______
= 1010 

Więc C dostaje część 010, a E dostaje 1. To jest oczekiwane zachowanie, jednak otrzymuję C tak samo, ale E jako 0. Myślę, że Verilog zwiększa rozmiary zmiennych RHS do 4 bitów, ponieważ lewa strona ma 4 bity ( 1 + 3). Jednak dla T dołącza początkowe 0 przed uzupełnieniem T, więc T staje się 0011, a jego uzupełnieniem jest 1100, zamiast 0100, 4-bitowa wersja uzupełnienia T.

A to prowadzi do

   0101
   1100
   0001
+______
= 10010 

Co powoduje, że E jest równe 0, jak widać.

Nie rozumiem, dlaczego tak jest i nie mogłem znaleźć sposobu na uzupełnienie danych przed dodaniem wiodącego zera.

Jeśli zamiast tego wykonam następujące czynności, wszystko działa dobrze, a E otrzymuje 1:

    U = 5;
    T = 3;
    T = ~T;
    {E, C} = U + T + 1'b1;

To potwierdza, że ​​moje podejrzenie jest słuszne. Więc mam takie rozwiązanie, tak. Jednak nie jestem z tego zadowolony, myślę, że powinien być sposób, aby temu zapobiec.

Każda pomoc będzie mile widziana.

Odpowiedzi

3 dave_59 Jan 14 2021 at 05:55

Jeśli masz operandy o różnych szerokościach, Verilog ma reguły określające rozmiar każdego operandu do szerokości największego operandu w oparciu o kontekst wyrażenia. Poprawnie zauważyłeś, że LHS ma 4 bity, a operandy na RHS są rozszerzane do 4 bitów. Dzieje się to przed zastosowaniem operacji.

Możesz to naprawić, wykorzystując fakt, że operandy konkatenacji są kontekstami samookreślonymi:

{E, C} = U + {~T} + 1'b1;

Teraz szerokość ~Tjest określana wyłącznie przez szerokość T.