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, что соответствует выходу симуляции.

Другие вопросы по тегам