先行进位加法

在看《计算机原理和设计:verilog HDL版》时,看到书中的先行进位加法,可是仿真下来却不对,书中的代码如下:

看过书很久了,发现这个东西一下子没有弄明白,从源头开始,重新整理,

s = a ^ b ^ c;
co = a & b | (a|b) & c;

主要看进位相关的  co = a & b | (a|b) & c;

P = a | b;
G = a & b;

对于每位的进位表示成

C(i) = G(i) | P(i) & C(i-1);

根据上式求出 C(i+1) 位

C(i+1) = G(i+1) | P(i+1) & C(i)
       = G(i+1) | P(i+1) & G(i) |  P(i+1) & P(i) & C(i-1);

令:

mg[i+1,i] = G(i+1) | P(i+1) & G(i);
mp[i+1,i] = P(i+1) & P(i);

则 C(i+1) 可以表求为:

C(i+1) = mg[i+1,i] | mp[i+1,i] & C(i-1);

再进一步求得 C(i+2) : 

C(i+2) = G(i+2) | P(i+2) & C(i+1);
       =  G(i+2) | P(i+2) & (G(i+1) | P(i+1) & G(i) |  P(i+1) & P(i) & C(i-1));
       =  G(i+2) | P(i+2) & G(i+1) | P(i+2) & P(i+1) & G(i) | P(i+2) & P(i+1) & P(i) & C(i-1);

那么:

mg[i+2,i] = G(i+2) | P(i+2) & G(i+1) | P(i+2) & P(i+1) & G(i)
          = G(i+2) | P(i+2) & mg[i+1,i]
        
mp[i+2,i] = P(i+2) & P(i+1) & P(i)
          = P(i+2) & mp[i+1,i]

上面就是一个递归式,代入小数 0 和 1 就更好的看明白其中的关系
       

mg[1,0] = G(1) | P(1) & G(0);
mp[1,0] = P(1) & P(0);

mg[2,1] = G(2) | P(2) & G(1);
mp[2,1] = P(2) & P(1);

mg[2,0] =  G(2) | P(2) & mg[1,0]
mp[2,0] =  P(2) & mp[1,0]

现在再来看代码就容易很多

module add(
	input a,
	input b,
	input c_in,
	output g,
	output p,
	output s
);

assign g = a & b;
assign p = a | b;
assign s = a ^ b ^ c_in;

endmodule 

module g_p(
	input [1:0] g,
	input [1:0] p,
	input c_in,
	output g_out,
	output p_out,
	output c_out
);

//c_out = c1 = g0 + p0c0;
//	  c2 = g1 + p1c1
//	  c2 = g1 + p1g0 + p1p0c0;
//	g_out= G(1,0) = g1+p1g0
//	c_out= P(1,0) = p1p0

assign c_out = g[0] | p[0] & c[0];
assign g_out = g[1] | p[1] & g[0];
assign p_out = p[1] & p[0];

endmodule 

module cal_2(
	input [1:0] a,
	input [1:0] b,
	input c_in,
	output g_out,
	output p_out,
	output [1:0] s,
);

	wire c_out;
	wire [1:0] p;
	wire [1:0] g;
	add a(a.(a[0]), .b(b[0]), .c_in(c_in), .g(g[0]), .p(p[0]), .s(s[0]));
	add b(a.(a[1]), .b(b[1]), .c_in(c_out), .g(g[1]), .p(p[1]), .s(s[1]));

	g_p c(.g(g),.p(p),c_in,.g_out(g_out),.p_out(p_out),.c_out(c_out));

endmodule

module cal_4(
	input [3:0] a,
	input [3:0] b,
	input c_in,
	output g_out,
	output p_out,
	output [3:0] s,
);

	wire c_out;
	wire [1:0] p;
	wire [1:0] g;
	cal_2 a(.a(a[1:0]), .b(b[1:0]), .c_in(c_in), .g(g[0]), .p(p[0]), .s(s[1:0]));
	cal_2 b(.a(a[3:2]), .b(b[3:2]), .c_in(c_out), .g(g[1]), .p(p[1]), .s(s[3:2]));

	g_p c(.g(g),.p(p),c_in,.g_out(g_out),.p_out(p_out),.c_out(c_out));

endmodule

仔细才发现,这代码其实只把进1,3,5,9,17,33位进位算对了,也就是最高位的进位是对了。

这个没有办法,只好写了一个不科学的方法,代码和上面一样, 只是路径太长有 32步,没有起到真正的并发效果,也没有缩短路径,还是32步。

module add32_ab(a, b, ci,  co);
	input a, b, ci;
	wire g, p;
	output co;
	
	assign g = a & b;
	assign p = a | b;
	assign co = g | p & ci;
	
endmodule



module cal2_ab(a, b, ci,   co);
	input [1:0] a, b;
	input ci;

	output [1:0] co;
	
	add32_ab ander1(a[0], b[0], ci,  co[0]);
	add32_ab ander2(a[1], b[1], co[0], co[1]);
	
endmodule


module cal4_ab(a, b, ci,   co);
	input [3:0] a, b;
	input ci;

	output [3:0] co;


	
	cal2_ab ander2(a[1:0], b[1:0], ci,  co[1:0]);
	cal2_ab ander1(a[3:2], b[3:2], co[1], co[3:2]);
	

	
endmodule


module cal8_ab(a, b, ci,   co);
	input [7:0] a, b;
	input ci;

	output [7:0] co;


	
	cal4_ab ander2(a[3:0], b[3:0], ci, co[3:0]);
	cal4_ab ander1(a[7:4], b[7:4], co[3],  co[7:4]);
	

	
endmodule

module cal16_ab(a, b, ci,   co);
	input [15:0] a, b;
	input ci;

	output [15:0] co;


	
	cal8_ab ander2(a[7:0], b[7:0], ci, co[7:0]);
	cal8_ab ander1(a[15:8], b[15:8], co[7],  co[15:8]);
	

	
endmodule


module cal32_ab(a, b, ci,   co);
	input [31:0] a, b;
	input ci;

	output [31:0] co;

	cal16_ab ander2(a[15:0], b[15:0], ci, co[15:0]);
	cal16_ab ander1(a[31:16], b[31:16], co[15], co[31:16]);
	
endmodule


module add_ab(a, b, ci, s, c_out);
	input [31:0] a, b;
	input ci;
	output [31:0] s;
	output c_out;
	wire [31:0] co;
	
	
	cal32_ab caler(a, b, ci, co);
	assign c_out = co[31];
	assign s = a ^ b ^ {co[30:0], ci};
	
endmodule


暂时没有想到好的解决办法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值