Verilog mudando o tamanho do lado direito
Eu tenho um módulo básico como se segue para demonstrar algo.
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
O que eu espero é que E seja 1, porque;
U
é 101
T
é 011
e U + ~T + 001
é,
101
100
001
+______
= 1010
Então, C tem 010 parte e E tem 1. Este é o comportamento esperado, no entanto, eu tenho C igual, mas E como 0. Acho que verilog está aumentando o tamanho das variáveis RHS para 4 bits porque o lado esquerdo tem 4 bits ( 1 + 3). No entanto, para T, ele acrescenta 0 à esquerda antes de complementar T, então T torna-se 0011 e seu complemento passa a ser 1100, em vez de 0100, versão de 4 bits do complemento T.
E isso leva a,
0101
1100
0001
+______
= 10010
O que faz com que E seja 0 conforme visto.
Não entendo por que isso acontece e não consegui encontrar uma maneira de fazer a complementação acontecer antes de adicionar um zero à esquerda.
Se eu fizer o seguinte, funcionará bem e E terá 1:
U = 5;
T = 3;
T = ~T;
{E, C} = U + T + 1'b1;
Isso confirma que minha suspeita está certa. Então, eu tenho essa solução, sim. No entanto, não estou muito satisfeito com isso, acho que deveria haver uma maneira de evitar esse comportamento.
Qualquer ajuda seria apreciada.
Respostas
Quando você tem operandos de mistura de larguras diferentes, Verilog tem regras para dimensionar cada operando para a largura do maior operando com base no contexto da expressão. Você observou corretamente que o LHS tem 4 bits, os operandos no RHS são estendidos para 4 bits. Isso acontece antes de aplicar a operação.
Você pode corrigir isso aproveitando o fato de que operandos de uma concatenação são contextos autodeterminados:
{E, C} = U + {~T} + 1'b1;
Agora, a largura de ~T
é determinada exclusivamente pela largura de T
.