Algorithm verilog中的add和shift

Algorithm verilog中的add和shift,algorithm,verilog,multiplication,Algorithm,Verilog,Multiplication,这是我关于加法和移位乘法的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;

这是我关于加法和移位乘法的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
多模块(a、b、ans);
输入[3:0]a;
输入[3:0]b;
输出寄存器[15:0]ans;
reg[15:0]aa;
reg[15:0]bb;
reg[15:0]tmp=0;
reg标志=1'b1;
始终@(a,b)
开始
aa=a;
bb=b;
while(标志==1'b1)
开始
if(bb[0]==1'b1)
tmp=tmp+aa;
aa=aa>1;
如果(bb==0)
标志=1'b0;
结束
ans=tmp;
结束
端模

这段代码有很多地方看起来很奇怪

首先,您没有时钟输入,但正在尝试使用组合逻辑来完成所有操作

第二,在reg语句中将flag设置为1将意味着您的模块只能执行一次乘法。顺便说一句,使用复位信号比在寄存器行中使用这种初始化更正常(特别是对于ASIC设计)

第三,4位数字乘以4位数字将得到8位答案,而不是16位

在任何情况下,除非您以非常高的速度工作,否则您应该能够在一个周期内执行乘法运算

这里有几种更自然地编写代码的方法:

组合风格 计时式
多模块(时钟、a、b、ans);
输入[3:0]a;
输入[3:0]b;
输出寄存器[7:0]ans;
始终@(posedge clk)
开始

ans您的输入是4位宽,并且您分配给16位变量时,前12位是未分配的,即
x

input [3:0] a;
reg [15:0] aa;
//...
aa = a;
要分配
aa
的所有位,请尝试以下操作:

aa = {12'b0, a}; 
//{} is bit concatenation 
或者要将a扩展到16位,请使用
{width{value}}
复制将MSB重复12次:

aa = {{12{a[3]}}, a}; 

您的顶级测试台是什么?
aa = {12'b0, a}; 
//{} is bit concatenation 
aa = {{12{a[3]}}, a};