完成后面的习题,这里以16位为测试,通过改变N,可以实现N位乘法阵列.下面是Verilog代码.
- module hw_mul(x, y, out);
- parameter n = 16;
- input [n-1:0]x, y;
- output [n*2-1:0]out;
- genvar i, j, k, l;
- wire [n:0]tmp_sun[n-1], tmp_out[n-1];
- wire [n:0]tmp_x;
-
- assign tmp_x = {1'b0,x};
- assign out[0] = tmp_x[0] & y[0];
- generate
- assign tmp_out[0][0] = 1'b0;
- for(i=0;i<n;i=i+1)//循环相加顶层乘数的前两位与上被乘数的部分积.
- begin:add_bt
- top_m tm (tmp_x[i+1], y[0], tmp_x[i], y[1], tmp_out[0][i], tmp_sun[0][i], tmp_out[0][i+1]);
- end
- assign out[1] = tmp_sun[0][0];
- assign tmp_sun[0][n] = tmp_out[0][n];
-
- for(j=2;j<n;j=j+1)//从第三位开始的每一位与上被乘数,然后跟上一层的部分积结果相加.
- begin:ftf
- for(k=0;k<n;k=k+1)
- begin:add_bb
- btm_m bm (tmp_sun[j-2][k+1], tmp_x[k], y[j], tmp_out[j-1][k], tmp_sun[j-1][k], tmp_out[j-1][k+1]);
- end
- assign out[j] = tmp_sun[j-1][0];
- assign tmp_sun[j-1][n] = tmp_out[j-1][n];
- end
-
- for(l=n;l<n*2;l=l+1)
- begin:add_o
- assign out[l] = tmp_sun[n-2][l-n+1];
- end
- endgenerate
- endmodule
- module top_m(m0, q0, m1, q1, cin, sun, cout);//顶层乘法单元
- input m0, m1, q0, q1;
- input cin;
- output sun, cout;
- wire x, y;
-
- assign x = m0 & q0;
- assign y = m1 & q1;
- full_add fa (x, y, cin, sun, cout);
- endmodule
- module btm_m(sunin, m, q, cin, sun, cout);//下层乘法单元
- input sunin, m, q, cin;
- output sun, cout;
- wire y;
-
- assign y = m & q;
- full_add fa (sunin, y, cin, sun, cout);
- endmodule
- module full_add(x, y, cin, sun, cout);//一位全加器
- input x, y, cin;
- output reg sun, cout;
- always@(x, y, cin)
- begin
- sun <= x^y^cin;
- cout <= x&y | x&cin | y&cin;
- end
- endmodule
下面是该乘法阵列的功能仿真.
小结:
Verilog的循环性语句,如for,while并不像C语言那样有指令判断条件再跳转之类的,这里的循环是给编译器用的,它只是按你给定的循环重复生成N个用给定的线网连接起来的模块,等于你手工写重复模块一样的.
阅读(3317) | 评论(0) | 转发(0) |