Verilog-код с неправильной формой волны (схема Mutliplier)
module multiplication (multiplier, multiplicand, product, clk);
input [3:0] multiplier;
input [4:0] multiplicand;
input clk;
output [7:0] product;
reg [7:0] product;
initial
begin
product [7:4] = 4'b0000;
product [3:0] = 4'b1100;
end
always @ (posedge clk)
begin
if (product[0] == 1)
begin
product <= product >> 1;
product[7:3] <= product[7:3] + multiplicand[4:0];
end
else
begin
product <= product >> 1;
end
end
endmodule
Этот код verilog предназначен для реализации схемы, упомянутой в этом вопросе: Как выполнить двоичное умножение со сдвигом вправо?, форма сигнала верна до последнего шага. Правильный ответ должен быть 00111100
1 ответ
С чего бы это?
Мы знаем при t=300 нс, product[0]==1
Таким образом, мы используем первый вариант if-else. В этом случае у нас есть следующее:
product <= product >> 1;
product[7:3] <= product[7:3] + multiplicand[4:0];
Поскольку вы (правильно) используете неблокирующие назначения, значение product
не обновляется, пока не завершится блок Always. Это означает, что во втором назначении используется несмещенное значение продукта. Мы могли бы упростить это выражение как
product[2:0] <= product [3:1];
product[7:3] <= product[7:3] + multiplicand[4:0];
и результат будет таким же.
Первое утверждение даст нам 0b100
, Второе дает нам 0b00101 + 0b00101 = 0b01010
, Всего получается 0b01010100
, что соответствует выходу симуляции.