Модуль Verilog для АЛУ, но не работает должным образом
Я пытаюсь записать АЛУ для Verilog. И есть несколько ошибок, которые я испытываю.
Прежде всего, вот мой код:
module yAlu(z, ex, a, b, op);
input [31:0] a, b;
input [2:0] op;
output [31:0] z, ztemp;
output ex;
wire[31:0]a0,a1,a2,a3,a4, atemp;
assign slt = 0;
assign ex = 0;
assign a0 = a & b;
assign a1 = a | b;
assign a2 = a + b;
assign a3 = a - b;
assign a4 = a[31] ^ b[31];
yMux #(32) lo(zLo, a0, a1, op[0]);
yMux #(32) hi(zHi, a2, a3, op[0]);
yMux #(32) temp(atemp, zLo, zHi, op[1]);
assign z = (op[2] == 1) ? a4 : atemp;
assign slt = z;
endmodule
И yAlu.v использует следующее:
module yMux(z, a, b, c);
parameter SIZE = 2;
output [SIZE-1:0] z;
input [SIZE-1:0] a, b;
input c;
yMux1 mine[SIZE-1:0](z, a, b, c); // 2-bit 2 -to-1 mux and it would be cumbersome to write 32 mux instantiation lines.
endmodule
Наконец, в yMux используется следующее:
module yMux1(z, a, b, c);
output z;
input a, b, c;
wire notC, upper, lower;
// Gates and interconnections for MUX
// if c is 0, z=a.
// if c is 1, z=b
not my_not(notC, c);
and upperAnd(upper, a, notC);
and lowerAnd(lower, c, b);
or my_or(z, upper, lower);
endmodule
Вот что он тестирует выше yAlu:
module lab8;
reg [31:0] a, b;
reg [31:0] expect;
reg [2:0] op;
wire ex;
wire [31:0] z;
reg ok, flag;
yAlu mine(z, ex, a, b, op);
initial begin
repeat (10) begin
a = $random; b = $random;
if(op==0)
expect = a & b;
else if (op==1)
expect = a | b;
else if (op==2)
expect = a + b;
else if (op==3)
expect = a - b;
else if (op==4)
expect = (a < b) ? 1 : 0;
#1;
if(expect == z)
$display("PASS : expected=%d, a=%d, b=%d, z=%d, op=%d", expect,a,b,z,op);
#1;
$finish;
end
end
endmodule
Мои вопросы в порядке следования:
Question 1.
Код выше работает только для 0 и 1. Он не работает больше, чем это. Например, на втором исходном коде есть
a = $random; b = $ случайный;
это не работает для этого. это работает только когда a=1 или 0 и b=1 или 0.
Question 2.
Я не уверен, что функция "slt" работает правильно. Преподаватель, который учит этому, никогда не говорил мне, что делает slt на лекции, но заставляет нас разрабатывать slt, прибегая к помощи googling или что-то еще.
Question 3.
Всякий раз, когда я компилирую, я получаю следующую ошибку. Почему это?
yAlu.v:38: warning: Port 1 (z) of yMux expects 32 bits, got 1.
yAlu.v:38: : Padding 31 high bits of the port.
yAlu.v:39: warning: Port 1 (z) of yMux expects 32 bits, got 1.
yAlu.v:39: : Padding 31 high bits of the port.
yAlu.v:40: warning: Port 2 (a) of yMux expects 32 bits, got 1.
yAlu.v:40: : Padding 31 high bits of the port.
yAlu.v:40: warning: Port 3 (b) of yMux expects 32 bits, got 1.
yAlu.v:40: : Padding 31 high bits of the port.
I can't fix this at all.
Я даже не знаю, правильно ли я это делаю. Руководство, которое направляет меня делать то, что в нем говорится, не имеет достаточного объяснения, а также не содержит примеров.
В любом случае я не смог вовремя закончить, так что, думаю, это не имеет значения, но я думаю, что должен знать решение своих проблем.
Большое спасибо, если вы можете мне помочь.
1 ответ
Как видно из предупреждений, ширина вашего порта подключения не соответствует. Обратитесь к одному предупреждению, а другие - к тому же.
yAlu.v:38: warning: Port 1 (z) of yMux expects 32 bits, got 1.
yAlu.v:38: : Padding 31 high bits of the port.
Модуль объявляет порты a
, b
, c
а также z
каждая ширина определена как SIZE
параметр.
module yMux(z, a, b, c);
parameter SIZE = 2;
output [SIZE-1:0] z;
input [SIZE-1:0] a, b;
Кроме того, SIZE
перезаписывается при создании экземпляра. Теперь значение SIZE
32. Следовательно, ширина каждого из a
, b
, c
а также z
32-битный
yMux #(32) lo(zLo, a0, a1, op[0]);
yMux #(32) hi(zHi, a2, a3, op[0]);
yMux #(32) temp(atemp, zLo, zHi, op[1]);
Здесь порты zLo
, zHi
не объявлен и не используется напрямую при подключении к порту.
Ссылаясь на IEEE 1800-2012, раздел 6.10- Неявные декларации:
Если идентификатор используется в объявлении выражения порта, то должна подразумеваться неявная сеть типа сети по умолчанию с векторной шириной объявления выражения порта.
Это, если необъявленный идентификатор используется в качестве соединения с экземпляром, то подразумевается неявная сеть.
Таким образом, zLo
, zHi
неявно объявляются как однобитовые сети, а остальные 32- битные заполняются нулями. Просто объявите их следующим образом, и все предупреждения будут удалены:
wire [31:0] zLo,zHi;
Чтобы получить ошибку в такой ситуации, используйте default_nettype none
директива компилятора.
Для получения дополнительной информации обратитесь к статье Sutherland SV Gotchas, раздел 2.2, и SystemVerilog IEEE 1800-2012 для неявных объявлений.