verilog 刷题记录-牛客网-组合逻辑-加法器系列

verilog 刷题记录-牛客网-组合逻辑系列-加法器

一、四位数值比较器电路

某4位数值比较器的功能表如下。 请用Verilog语言采用门级描述方式,实现此4位数值比较器

根据图表写逻辑表达就可以

`timescale 1ns/1ns

module comparator_4(input		[3:0] A 	,
                    input	 [3:0]		B 	,
                    output	 wire		Y2,  //A>B
                    output wire Y1,    //A = B
                    output wire Y0);   //A<B
    
    assign Y2 = (A[3]> B[3]) |((A[3] == B[3])&&(A[2]> B[2])) | ((A[3] == B[3])&&(A[2] == B[2])&&(A[1]> B[1])) |((A[3] == B[3])&&(A[2] == B[2])&&(A[1] == B[1])&&(A[0]> B[0]));
    assign Y1 = ((A[3] == B[3])&&(A[2] == B[2])&&(A[1] == B[1])&&(A[0] == B[0]));
    assign Y0 = (~Y1)& (~Y2);
endmodule

其实就是费时间,需要根据表格实现对应的逻辑

二、4bit超前进位加法器电路

在这里梳理一下加法器

对加法器进行梳理,首先加法器可以分为一位数加法器和多位加法器,而一位加法器又可以分为半加器和全加器,对于全加器和半加器,是在于有木有来自低位的进位

(1) 半加器

半加器是最简单的加法器,并不考虑进位输出,所以一般其verilog语言为

assign S     = A ^ B;
assign C_out = A & B;

半加器的电路又是怎么样的呢

加法器总结

(2) 全加器

考虑来自低位的进位,就会有一种情况,大致的一个思路是,先根据真值表写出逻辑表达式,再根据逻辑表达式,进行电路的设计。
逻辑表达式
Si=Ai⊕Bi⊕Ci-1
在这里插入图片描述
电路图原理
在这里插入图片描述
可以利用其电路描述,即直接利用组合逻辑进行书写

assign s  = A^B^C_i;
assign Cout = A & B | C_i & (A & B);

也可以利用结构性描述,利用两个半加器进行描述

wire w1,w2,w3;
    adder_half u1(.a(a),.b(b),.sum(w1),.cout(w2));
    adder_half u2(.a(cin),.b(w1),.sum(sum),.cout(w3));
assign cout = w2 | w3;

同时也可以使用行为级描述

assign {count, sum } = a+b+cin;

不过一开始学习还是要知道组合逻辑描述,基本上看到表达式就可以想到电路结构

(3)多位加法器

串行进位加法器
两个多位数相加时,每一位都是带进位相加的,因此必须使用全加器,所以只要依次将低位全加器的进位接到全加器的输入端,就可以构成多位加法器。
电路图
电路图
在这里插入图片描述
所以其写法也很简单,只需要将封装好的全加器模块进行调用即可。
将上面的全加器封装为fulladder

module serialadder(
                   output   [3:0]   s,
                   output           co,
                   input    [3:0]   a,
                   input    [3:0]   b,
                   input            ci
                   );
wire   [3:0]   co_tmp;

fulladder   u_add0(
                   .s(s[0]),  //sum
                   .co(co_tmp[0]), //carry to high bit
                   .a(a[0]),  
                   .b(b[0]),
                   .ci(ci)  //carry from low bit
                   );

fulladder   u_add1(
                   .s(s[1]),  //sum
                   .co(co_tmp[1]), //carry to high bit
                   .a(a[1]),  
                   .b(b[1]),
                   .ci(co_tmp[0])  //carry from low bit
                   );

fulladder   u_add2(
                   .s(s[2]),  //sum
                   .co(co_tmp[2]), //carry to high bit
                   .a(a[2]),  
                   .b(b[2]),
                   .ci(co_tmp[1])  //carry from low bit
                   );

fulladder   u_add3(
                   .s(s[3]),  //sum
                   .co(co_tmp[3]), //carry to high bit
                   .a(a[3]),  
                   .b(b[3]),
                   .ci(co_tmp[2])  //carry from low bit
                   );

assign   co = co_tmp[3];

endmodule

(4)超前进位加法器

其实现的逻辑为:串行进位加法器体现了电路设计的重复利用,同时降低了运算速度,如何才能够减少由于进位信号逐级传递的所消耗的时间呢。
先通过逻辑电路得到每一个全加器的进位输入信号,无需从最低位传递信号,大大缩减了计算时间。

其电路也会更加复杂。
在这里插入图片描述

`timescale 1ns / 1ps
// Description: 
 module Carry_Lookahead_Adder(
input   [3:0]       A           ,
input   [3:0]       B           ,
input               Cin         ,
output  [3:0]       S           ,
output              Cout
    );
 
wire c1,c2,c3;
//  超前进位算法
assign c1 = (A[0]&B[0]) |((A[0]^B[0])&Cin) ;
assign c2 = (A[1]&B[1]) |((A[1]^B[1])&c1 ) ;
assign c3 = (A[2]&B[2]) |((A[2]^B[2])&c2 ) ;
assign Cout = (A[3]&B[3])|((A[3]^B[3])&c3 ) ;

assign S = {A[3]^B[3]^c3,A[2]^B[2]^c2,A[1]^B[1]^c1,A[0]^B[0]^Cin}; 
endmodule

最后S是实现上图中的逻辑式
或者利用这个

module carry_look_aheadadder(
                             output     [3:0]   s,
                             output             co,
                             input      [3:0]   a,
                             input      [3:0]   b,
                             input              ci
                             );
wire  [3:0]    co_tmp;
wire  [3:0]    cin;

assign  cin[3:0]  = {co_tmp[2:0],ci};

//计算中间进位
assign  co_tmp[0] = a[0]&b[0] || (a[0] || b[0])&(cin[0]);
assign  co_tmp[1] = a[1]&b[1] || (a[1] || b[1])&(cin[1]);
assign  co_tmp[2] = a[2]&b[2] || (a[2] || b[2])&(cin[2]);
assign  co_tmp[3] = a[3]&b[3] || (a[3] || b[3])&(cin[3]);

//计算和
assign s[0] = a[0] ^ b[0] ^ cin[0];
assign s[1] = a[1] ^ b[1] ^ cin[1];
assign s[2] = a[2] ^ b[2] ^ cin[2];
assign s[3] = a[3] ^ b[3] ^ cin[3];

assign co = co_tmp[3];
endmodule

然后搭建验证平台

module carry_look_aheadadder_tb;
wire      [3:0]       s;
wire                  co;
reg       [3:0]       a;
reg       [3:0]       b;
reg                   ci;

initial
begin
          a = 4'b0000; b = 4'b0000; ci = 0; 
    #10   a = 4'b1111; b = 4'b1111; ci = 0; 
    #10   a = 4'b1100; b = 4'b1001; ci = 0; 
    #10   a = 4'b0111; b = 4'b0110; ci = 0; 
    #10   a = 4'b0101; b = 4'b0101; ci = 1; 
    #10   a = 4'b1110; b = 4'b1001; ci = 1; 
    #10   a = 4'b0010; b = 4'b0110; ci = 1; 
    #10   a = 4'b0110; b = 4'b1100; ci = 1; 
    #10   $finish;
end

initial begin
  $fsdbDumpfile("test.fsdb");
  $fsdbDumpvars();
end

carry_look_aheadadder u_carry_look_aheadadder(
                                              .s(s),
                                              .co(co),
                                              .a(a),
                                              .b(b),
                                              .ci(ci)
                                              );

endmodule

进行仿真模拟

对于这道题目是实现4bit超前进位加法器
就按照给的逻辑进行实现就可以

`timescale 1ns/1ns

module lca_4(
	input		[3:0]       A_in  ,
	input	    [3:0]		B_in  ,
    input                   C_1   ,
 
 	output	 wire			CO    ,
	output   wire [3:0]	    S
);
    wire [3:0] G;
    wire [3:0] P;
    assign G[0] = A_in[0] & B_in[0];
    assign G[1] = A_in[1] & B_in[1];
    assign G[2] = A_in[2] & B_in[2];
    assign G[3] = A_in[3] & B_in[3];  
    
    assign P[0] = A_in[0] ^ B_in[0];
    assign P[1] = A_in[1] ^ B_in[1];
    assign P[2] = A_in[2] ^ B_in[2];
    assign P[3] = A_in[3] ^ B_in[3];  
    
    wire [3:0] C;
    assign C[0] = G[0] | P[0]&C_1;
    assign C[1] = G[1] | P[1]&C[0];
    assign C[2] = G[2] | P[2]&C[1];
    assign C[3] = G[3] | P[3]&C[2]; 
    
    assign CO = C[3];
    assign S[0] = P[0] ^ C_1;
    assign S[1] = P[1] ^ C[0];
    assign S[2] = P[2] ^ C[1];
    assign S[3] = P[3] ^ C[2];     
    
    
endmodule

参考资料
加法器

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

约翰克里斯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值