【verilog学习15】HDLBits:Circuits_Combinational Logic_Arithmetic Circuits

I. Hadd (Halfadder)

1.代码编写

//==============================方法1==============================
module top_module( 
    input a, b,
    output cout, sum );
    assign {cout,sum}=a+b;
endmodule
//==============================方法2==============================
module top_module( 
    input a, b,
    output cout, sum );
    assign cout=a&b;
    assign sum=a^b;
endmodule

2.提交结果

在这里插入图片描述

3.题目分析

两种方法,行为级与门级。另外{cout,sum}不要乱序,其次,可以发现“{ }”用在“=”右侧左侧都可以。

II. Fadd (Fulladder)

1.代码编写

//=================================方法一=================================
module top_module( 
    input a, b, cin,
    output cout, sum );
    assign {cout,sum}=a+b+cin;
endmodule
//=================================方法二=================================
module top_module( 
    input a, b, cin,
    output cout, sum );
    assign cout=a&b+cin&(a^b);
    assign sum=a^b^cin;
endmodule
//门级电路表达

2.提交结果

success

3.题目分析

两种方式,行为级和门级。

III. Adder3 (3-bit binary adder)

1.代码编写

//=======================方法1========================
module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    fadder instance1(.a(a[0]),.b(b[0]),.cin(cin),.cout(cout[0]),.sum(sum[0]));
    fadder instance2(.a(a[1]),.b(b[1]),.cin(cout[0]),.cout(cout[1]),.sum(sum[1]));
    fadder instance3(.a(a[2]),.b(b[2]),.cin(cout[1]),.cout(cout[2]),.sum(sum[2]));
endmodule

module fadder(
    input a,b,cin,
	output cout,sum);
    assign {cout,sum}=a+b+cin;
endmodule

//========================这样写复习一下task(发现task A后面忘加;,已改正)========================
module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
	task A;
        input a,b,cin;
        output sum,cout;
        {cout,sum}=a+b+cin;
    endtask
    always@(*) begin
        A(a[0],b[0],cin,sum[0],cout[0]);
        A(a[1],b[1],cout[0],sum[1],cout[1]);
        A(a[2],b[2],cout[1],sum[2],cout[2]);
    end
endmodule

2.提交结果

success

3.题目分析

有关verilog输入输出的介绍:

https://blog.csdn.net/qq_34670678/article/details/106432116

几点总结:

  • input,output,inout未声明时的默认类型为wire型
  • test文件输入端口只能是net型(wire)输出端口可以是wire/reg。因为输入端不用储存数据,只是反映输入信号的变化,是连线关系,而输出端可能要存储数据。
  • testbench文件的输入可以是wire/reg,而输出只能是net型(wire)。因为testbench用于产生虚拟信号时,需要输出至test文件的输入端,testbench的输出相当于test的输入,用net。而testbench文件用于存储test的输出结果时,testbench的输入相当于test的输出,可以用reg/net型。

IV. Exams/m2014 q4j (Adder)

1.代码编写

//=============================method 1=============================
module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    wire c2,c3,c4;
    FA instance1(.x(x[0]),.y(y[0]),.cin(),.cout(c2),.sum(sum[0]));
    FA instance2(.x(x[1]),.y(y[1]),.cin(c2),.cout(c3),.sum(sum[1]));
    FA instance3(.x(x[2]),.y(y[2]),.cin(c3),.cout(c4),.sum(sum[2]));
    FA instance4(.x(x[3]),.y(y[3]),.cin(c4),.cout(sum[4]),.sum(sum[3]));
endmodule
module FA(
	input x,y,cin,
    output cout,sum);
    assign {cout,sum}=x+y+cin; //verilog默认未声明的输入输出端口为net型,这里用assign,否则报错:‘near text: "{";  expecting "endmodule". ’
endmodule
//=============================review task=============================
module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    wire c2,c3,c4;
	task FA;
        input x,y,cin;
        output cout,sum;
        {cout,sum}=x+y+cin;
    endtask
    always@(*) begin
        FA(x[0],y[0],1'd0,c2,sum[0]);
        FA(x[1],y[1],c2,c3,sum[1]);
        FA(x[2],y[2],c3,c4,sum[2]);
        FA(x[3],y[3],c4,sum[4],sum[3]);
    end
endmodule
//实际上在最低位的全加器上多了一个输入 cin=1'd0。

2.提交结果

success

3.题目分析

用两种方法分别实现了一下,发现用module的方法时,新的module里赋值记得用assign,因为未声明的输入输出端口默认为net。

V. Exams/ece241 2014 q1c (signed addition overflow)

1.代码编写

  • 正确代码:
  • 方法1:
    通过进位位来判断overflow,存在真值表:
    在这里插入图片描述
    可见overflow=c[7]^c[6]。
//=====================method 1=====================
module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
    wire [7:0] c;
    integer i;
    assign {c[0],s[0]}=a[0]+b[0];
    always@(*) begin
        for(i=1;i<8;i++)begin
            {c[i],s[i]}=a[i]+b[i]+c[i-1];
        end
    end
    assign overflow=c[7]^c[6];
endmodule
  • 方法2:
    通过对比a[7],b[7],s[7]来解决:
    overflow指的是:A signed overflow occurs when adding two positive numbers produces a negative result, or adding two negative numbers produces a positive result.
    在这里插入图片描述
module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
    assign s=a+b;
    assign overflow=a[7]&b[7]&~s[7]|~a[7]&~b[7]&s[7];
endmodule

  • 一种错误写法(运用行为级代码):
module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); //
    wire [7:0] c;
    // assign s = ...
    // assign overflow = ...
    assign {c,s}=a+b;
    assign overflow=c[7]^c[6];
endmodule

这样写存在mismatch:
在这里插入图片描述
仿真发现c只能反映最高位是否进位了

//======================test======================
module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
	output [7:0] c,
    output overflow
); //
    // assign s = ...
    // assign overflow = ...
    assign {c,s}=a+b;
    assign overflow=c[7]^c[6];
endmodule
//======================testbench======================
`timescale 1ns/1ps
module testbench();
reg [7:0] a,b;
wire [7:0] s,overflow,c;
initial begin
	a=8'h0;
	b=8'h0;
	#5 b=8'h70;
	#5 a=8'h70;
	#5 b=8'h90;
	#5 
	a=8'h90; 
	b=8'h70;
	#5 b=8'h90;
	#5 b=8'hff;
	#5 $stop;
end

top_module instance1(
	.a(a),
	.b(b),
	.s(s),
	.c(c),
	.overflow(overflow));
endmodule

波形:
在这里插入图片描述
证实c进反映了最高位的进位。

2.提交结果

success

3.题目分析

在代码编写部分。

VI. Adder100 (100-bit binary adder)

1.代码编写

module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    assign {cout,sum}=a+b+cin;
endmodule

2.提交结果

success

3.题目分析

Create a 100-bit binary adder. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out.

Expected solution length: Around 1 line.
Hint:There are too many full adders to instantiate, but behavioural code works well here.
有关行为级、RTL级、门级:

行为级:行为级是RTL级的上一层。最符合人类思维的描述方式。主要用于快速验证算法的正确性不关注电路的具体结构不一定可以综合成实际电路结构。注重算法。以直接赋值的形式进行,只关注结果。常采用大量运算,延迟等无法综合的语句。其目的不在于综合,而在于算法
RTL级:使用寄存器这一级别的描述方式来描述电路的数据流方式。RTL在很大程度上是对流水线原理图的描述。接近实际电路结构的描述,可以精确描述电路的原理、执行顺序等。其目的在于可综合
门级:使用逻辑门这一级别来描述。RTL 中的寄存器和组合逻辑,其物理实现还是对应到具体门电路。但目前寄存器,组合逻辑等的电路结构基本稳定。一般EDA工具可以把RTL描述自动编译为门级描述。所以一般不直接使用门级编程。
————————————————
版权声明:本文为CSDN博主「YUI不可爱」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012694677/article/details/89601675

VII. Bcdadd4 (4-digit BCD Adder)

1.代码编写

module top_module ( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
    wire c2,c3,c4;
    bcd_fadd instance1(.a(a[3:0]),.b(b[3:0]),.cin(cin),.cout(c2),.sum(sum[3:0]));
    bcd_fadd instance2(.a(a[7:4]),.b(b[7:4]),.cin(c2),.cout(c3),.sum(sum[7:4]));
    bcd_fadd instance3(.a(a[11:8]),.b(b[11:8]),.cin(c3),.cout(c4),.sum(sum[11:8]));
    bcd_fadd instance4(.a(a[15:12]),.b(b[15:12]),.cin(c4),.cout(cout),.sum(sum[15:12]));
endmodule

2.提交结果

success

3.题目分析

You are provided with a BCD (binary-coded decimal) one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.

module bcd_fadd (
input [3:0] a,
input [3:0] b,
input cin,
output cout,
output [3:0] sum );
Instantiate 4 copies of bcd_fadd to create a 4-digit BCD ripple-carry adder. Your adder should add two 4-digit BCD numbers (packed into 16-bit vectors) and a carry-in to produce a 4-digit sum and carry out.
Hint

  • The BCD representation for the 5-digit decimal number 12345 is 20’h12345. This is not the same as 14’d12345 (which is 14’h3039).
  • The circuit is structured just like a binary ripple-carry adder, except the adders are base-10 rather than base-2.
  • BCD码是用4位二进制数来表示1位十进制数中的0~9这10个数码,是一种二进制的数字编码形式,用二进制编码的十进制代码。4位二进制相当于1位16进制,所以10进制12345表示成BCD码为(5*4)=20’h12345,而非简单的14’d12345。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值