今天学习了时序乘法器与序列乘法器,时序乘法器的思路是利用时钟做周期性乘法,具体内容见书籍《verilog 应用设计实例》的290页,代码如下:

module test_net(x_in, y_in, clk, ini, p_out, done);

parameter N = 8,
M = 4;

input clk, ini;
input [N - 1 : 0] x_in;
input [M - 1 : 0] y_in;
output reg done;
output reg [N + M - 1 : 0] p_out;

integer counter;
reg [M : 0] temp;
reg [N - 1 : 0] x_reg;
reg [M - 1 : 0] y_reg, p_reg;


always @(posedge clk)
begin
if(ini)
begin
x_reg <= x_in;
y_reg <= y_in;
p_reg <= 0;
counter <= 0;
done <= 0;
end
else if(counter < N)
begin
if(x_reg[0])
temp = y_reg + p_reg;
else
temp = p_reg;
x_reg <= {temp[0], x_reg[N - 1 : 1]};
p_reg <= temp[M : 1];
counter <= counter + 1;
end
else if(counter == N)
begin
p_out = {p_reg, x_reg};
done <= 1;
end
else
begin
done <= 0;
p_out = 0;
end
end

endmodule

 

在该段,如果if的执行语句使用的是非阻塞赋值,就会使得输出错误,原因是因为temp在 仿真中的初始状态就是高阻状态 ,非阻塞赋值段使得x_reg和p_reg输入的是temp的初始值高阻值,而不是if条件语句中赋予的值,所以输出会变成高阻值,所以如果下一步要操作使用上一步的变量值,需要注意阻塞赋值和非阻塞赋值问题。

 

而设计阵列乘法器的代码如下:

module ripple_carry_mult(x_in, y_in, p);
      parameter M = 4;
        parameter N = 4;
        input [M - 1 : 0] x_in;
        input [N - 1 : 0] y_in;
        output reg [N + M - 1 : 0] p;

        reg [N : 0] c_in [M : 0], p_in[M : 0], cout[M : 0], pout[M : 0];
        integer i, j;
        always @(x_in or y_in)
            begin 
             for(i = 0; i <= M - 1; i = i + 1)
                c_in[i][0] = 1'b0;
                 p_in[0] = 4'b0;
                for (i = 0; i <= M - 1; i = i + 1)
                     begin
                         for (j = 0; j <= N - 1; j = j + 1)
                              begin 
                                   mul_cell(x_in[i], y_in[j], c_in[i][j], p_in[i][j], cout[i][j], pout[i][j]);
                                    c_in[i][j + 1] = cout[i][j];
                                    if (j == 0)
                                        p[i] = pout[i][j];
                                    else
                                        p_in[i + 1][j - 1] = pout[i][j];
                                end
                                p_in[i + 1][N - 1] = c_in[i][N];
                        end
                 for (i = 0; i <= N - 1; i = i + 1)
                      begin
                           p[i + M] = p_in[M][i];
                        end
                end
                task mul_cell(input x_i, y_i, cin, pin, output c_out, p_out);
                   reg int_p;
                    begin
                      int_p = x_i & y_i;
                      c_out = (pin & cin) | (pin & int_p) | (cin & int_p);
                      p_out = cin ^ pin ^ int_p;
                    end
               endtask
                
endmodule
                                    
         

这里仿真出现的问题是,由于未为函数内部变量c_in, p_in等等赋初值0,虽然quartusii编译器会为他们赋默认值0,但是在仿真时变量将全部输出高阻状态,致使仿真波形失败,因此在任何程序中,必须全部进行赋初值操作,否则会给仿真带来不必要的困难。

原文地址:http://www.cnblogs.com/wangzhaolong/p/16830497.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性