Verilog 加法器和减法器(2)

类似半加器和全加器,也有半减器和全减器。

半减器只考虑当前两位二进制数相减,输出为差以及是否向高位借位,而全减器还要考虑当前位的低位是否曾有借位。它们的真值表如下:


image

对半减器,diff = x ^y, cin = ~x&y


image

对全减器,要理解真值表,可以用举列子的方法得到,比如4’b1000-4b'0001,则第一位对应0 1 0 1 1第二位对应的是0 0 1 1 1

从真值表中,可以得到 diff = x ^ y ^cout, cin = (~x&(y^cout))|(y&cout)

推导过程:diff = ~x&~y&cout + ~x&y&~cout +x&~y&~cout+x&y&cout=~x&(~y&cout+y&~cout)+x&(~y&~cout+y&cout)=~x&(y^cout)+x&~(y^cout)=x^y^cout;

cin = ~x&~y&cout+~x&y&~cout+~x&y&cout+x&y&cout=~x&(~y&cout+~x&~cout)+(~x+x)&y&cout=~x&(y^cout)+y&cout

注意:这儿 +和|都表示或。

半减器的verilog代码和testbench代码如下:

复制代码
module halfsub(x,y,d,cin);

  input x;
  input y;

  output d;
  output cin;

  assign d = x^y;
  assign cin = (~x)&y;


endmodule
View Code
复制代码
复制代码
`timescale 1ns/1ns
`define clock_period 20

module halfsub_tb;
  reg  x,y;

  wire cin; //carryover
  wire d;
  reg clk;

  halfsub halfsub_0(
						.x(x),
						.y(y),
						.d(d),
						.cin(cin)
                  );

  initial clk = 0;
  always #(`clock_period/2) clk = ~clk;

  initial begin
     x = 0;
     repeat(20)
	    #(`clock_period) x = $random;

  end

  initial begin
     y = 0;
     repeat(20)
	    #(`clock_period) y = $random;

  end


  initial begin
     #(`clock_period*20)
	  $stop;
  end


endmodule
View Code
复制代码

用rtl viewer,可以看到半减器逻辑图如下:


image

半减器功能验证的波形:

image


全减器的verilog代码和testbench代码如下:

复制代码
module fullsub(cout,x,y,d,cin);

  input cout; // carry out bit, borrowed by its next low bit
  input x;
  input y;

  output d;
  output cin;

  assign d = x^y^cout;
  assign cin = (~x&(y^cout))|(y&cout);


endmodule
View Code
复制代码
复制代码
`timescale 1ns/1ns
`define clock_period 20

module fullsub_tb;
  reg  x,y,cout;

  wire cin; //carryover
  wire d;
  reg clk;

  fullsub fullsub_0(
                  .cout(cout),
						.x(x),
						.y(y),
						.d(d),
						.cin(cin)
                  );

  initial clk = 0;
  always #(`clock_period/2) clk = ~clk;

  initial begin
     x = 0;
     repeat(20)
	    #(`clock_period) x = $random;

  end

  initial begin
     y = 0;
     repeat(20)
	    #(`clock_period) y = $random;

  end

   initial begin
     cout = 0;
     repeat(20)
	    #(`clock_period) cout = $random;

  end

  initial begin
     #(`clock_period*20)
	  $stop;
  end


endmodule
View Code
复制代码


用rtl viewer,可以看到全减器逻辑图如下:


image

全减器的功能验证波形:

image











posted on   迈克老狼2012  阅读(3189)  评论(0编辑  收藏  举报

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程

导航

< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示