Verilog zmienia rozmiar prawej strony
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 + 001
jest,
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
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ść ~T
jest określana wyłącznie przez szerokość T
.