当前位置:   article > 正文

4bit超前进位加法器电路

超前进位加法器

描述

4bit超前进位加法器的逻辑表达式如下:

中间变量:

 和:

进位: 

 请用Verilog语言采用门级描述方式,实现此4bit超前进位加法器,接口电路如下:

输入描述

  1. 输入信号:
  2. A_in[3:0],
  3. B_in[3:0]
  4. C_1
  5. 类型:wire

输出描述

  1. 输出信号:
  2. S[3:0]
  3. CO
  4. 类型:wire

 解题分析

        如果只是简单地将逻辑表达式转化为verilog语言,这道题算不上较难题。难点应该是借着这道题理解超前进位加法器。下面梳理一些常见的加法器。

半加器

        半加器是最简单的加法器。它不考虑进位输入。其中AB是两个加数,S是和,C_o是进位输出。

  1. assign S = A ^ B;
  2. assign C_out = A & B;

全加器

        全加器是多bit加法器的基础。Ci是进位输入。

 下图中红色路径是全加器的关键路径。

 代码为:

  1. module full_adder(
  2. input A,
  3. input B,
  4. input C_i,
  5. output S,
  6. output C_o
  7. );
  8. assign S = A ^ B ^ C_i;
  9. assign C_o = A & B | C_i&(a^b);
  10. // assign C_o = A & B | A & C_i | B & C_i; // 也可以
  11. endmodule

行波进位加法器

        Ripple-carry adder, RCA。将全加器串联起来。 虽然RCA结构简单易于理解,但容易看出,每一位的运算结果SkS_kSk​都要依赖进位CkC_{k}Ck​才能得出。如下图所示,这会使得RCA的关键路径变得很长,而长关键路径会让电路难以满足时序要求。

代码为:

  1. module rca #(
  2. parameter width = 4
  3. )(
  4. input [width-1:0] A,
  5. input [width-1:0] B,
  6. output [width-1:0] S,
  7. input C_i,
  8. output C_o
  9. );
  10. wire [width:0] C;
  11. genvar i;
  12. generate
  13. for (i=0; i<width; i=i+1)begin
  14. full_adder myadder(
  15. .A (A[i]),
  16. .B (B[i]),
  17. .C_i (C[i]),
  18. .S (S[i]),
  19. .C_o (C[i+1]),
  20. );
  21. end
  22. endgenerate
  23. assign C[0] = C_i;
  24. assign C_o = C[width];
  25. endmodule

超前进位加法器

        Lookahead Carry Adder,LCA。超前进位加法器的思想是并行计算进位Ck,以缩短关键路径。Ck​可以直接由加数得到。
        首先,令:

 然后有:

 对于4bit LCA有:

        超前进位加法器是通过公式直接导出最终结果与每个输入的关系,是一种用面积换性能的方法。
        对于4bit LCA,进位输出C4的计算路径如下:        

        只需要三级门电路就可以得到,并且同时还计算出了​等可以复用的结果。而根据之前的分析,RCA产生C4​需要3+2+2+2=9级路径。加法器宽度越大,性能优势越明显。但LCA的逻辑门扇入扇出比较大,面积和复杂度都比较高。
        下面的代码来自于参考资料 

  1. module pg_gen(
  2. input A,
  3. input B,
  4. output G,
  5. output P
  6. );
  7. assign G = A & B;
  8. assign P = A ^ B;
  9. endmodule
  10. module lca_4bit #( width=4 ) (
  11. input [width-1:0] op1,
  12. input [width-1:0] op2,
  13. input C_i,
  14. output [width-1:0] S,
  15. output C_o
  16. );
  17. wire [width-1:0] G;
  18. wire [width-1:0] P;
  19. wire [width:0] C;
  20. genvar i;
  21. for( i=0; i<width; i=i+1) begin
  22. pg_gen u_pg_gen(
  23. .A( op1[i]),
  24. .B( op2[i]),
  25. .G( G[i] ),
  26. .P( P[i] )
  27. );
  28. end
  29. assign C[0] = C_i;
  30. assign C[1] = G[0] || ( C[0] & P[0] );
  31. assign C[2] = G[1] || ( (G[0] || ( C[0] & P[0]) ) & P[1] );
  32. assign C[3] = G[2] || ( (G[1] || ( (G[0] || (C[0] & P[0]) ) & P[1])) & P[2] );
  33. assign C[4] = G[3] || ( (G[2] || ( (G[1] || ( (G[0] || (C[0] & P[0]) ) & P[1])) & P[2] )) & P[3]);
  34. assign C_o = C[width-1];
  35. genvar k;
  36. for( k=0; k<width; k=k+1) begin
  37. assign S[k] = P[k] ^ C[k];
  38. end
  39. endmodule

 最后实现代码为:

        注意+的优先级高于&^

  1. `timescale 1ns/1ns
  2. module lca_4(
  3. input [3:0] A_in ,
  4. input [3:0] B_in ,
  5. input C_1 ,
  6. output wire CO ,
  7. output wire [3:0] S
  8. );
  9. wire [3:0] C;
  10. assign S[0] = A_in[0] ^ B_in[0] ^ C_1;
  11. assign S[1] = A_in[1] ^ B_in[1] ^ C[0];
  12. assign S[2] = A_in[2] ^ B_in[2] ^ C[1];
  13. assign S[3] = A_in[3] ^ B_in[3] ^ C[2];
  14. assign C[0] = (A_in[0] & B_in[0]) || ((A_in[0] ^ B_in[0]) & C_1);
  15. assign C[1] = (A_in[1] & B_in[1]) || ((A_in[1] ^ B_in[1]) & C[0]);
  16. assign C[2] = (A_in[2] & B_in[2]) || ((A_in[2] ^ B_in[2]) & C[1]);
  17. assign C[3] = (A_in[3] & B_in[3]) || ((A_in[3] ^ B_in[3]) & C[2]);
  18. assign CO = C[3];
  19. endmodule

注:分析内容摘取网友,如有侵权请告删之。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Monodyee/article/detail/707950
推荐阅读
相关标签
  

闽ICP备14008679号