Добавить и сдвинуть в verilog
Вот мой verilog-код о сложении и умножении сдвига, когда я компилирую и инициализирую и добавляю входы и выходы для получения и моделирования сигналов, я не вижу никаких результатов, все это z... в чем проблема?
module multi(a, b, ans);
input [3:0] a;
input [3:0] b;
output reg [15:0] ans;
reg [15:0] aa;
reg [15:0] bb;
reg [15:0] tmp=0;
reg flag = 1'b1;
always @( a, b)
begin
aa = a;
bb = b;
while ( flag == 1'b1 )
begin
if( bb[0] == 1'b1 )
tmp = tmp + aa;
aa = aa << 1;
bb = bb >> 1;
if ( bb==0 )
flag = 1'b0;
end
ans = tmp;
end
endmodule
2 ответа
Есть несколько вещей, которые выглядят странно с этим кодом.
Во-первых, у вас нет тактового входа, но вы пытаетесь сделать все с помощью комбинаторной логики.
Во-вторых, установка флага в 1 в выражении reg будет означать, что ваш модуль способен выполнять только одно умножение. Кстати, более нормально (особенно для конструкции ASIC) использовать сигнал сброса, чем использовать эту инициализацию в строке reg.
В-третьих, 4-битное число, умноженное на 4-битное, приведет к 8-битному ответу, а не к 16-битному.
В любом случае, если вы не работаете на очень высоких скоростях, вы сможете выполнить умножение за один цикл.
Вот несколько способов более естественного написания этого кода:
Комбинаторный стиль
module multi(a, b, ans);
input [3:0] a;
input [3:0] b;
output reg [7:0] ans;
always @(*)
begin
ans = a * b;
end
endmodule
Часовой стиль
module multi(clk, a, b, ans);
input [3:0] a;
input [3:0] b;
output reg [7:0] ans;
always @(posedge clk)
begin
ans <= a * b;
end
endmodule
Ваш вход имеет ширину 4 бита, а вы присваиваете 16-битную переменную, верхние 12 бит не назначены, т.е. x
,
input [3:0] a;
reg [15:0] aa;
//...
aa = a;
Чтобы назначить все биты aa
попробуйте что-нибудь вроде:
aa = {12'b0, a};
//{} is bit concatenation
Или, чтобы подписать расширение до 16 бит, повторите MSB 12 раз, используя {width{value}}
репликация:
aa = {{12{a[3]}}, a};