• 欢迎光临~

HDLbits第四天

开发技术 开发技术 2022-11-25 次浏览

出于对FPGA学习巩固的目的,同时也希望能锻炼自己对于Verilog的题目分析,让自己对HDL代码的理解加深,所以想坚持写一下关于HDLbits网站刷题的系列,计划是工作日每日5题目+分析,周末每日十题+分析(如果题目繁琐会减轻数量,以能够分析准确并理解为主)


Verilog Language

Modules: Hierarchy

adder1

HDLbits第四天
Module add

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cout1;
    wire cout2;

    add16 u1_add16(
        .a(a[15:0]),
        .b(b[15:0]),
        .cin(1'b0),
        .cout(cout1),
        .sum(sum[15:0])
    );
    
    add16 u2_add16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(cout1),
        .cout(cout2),
        .sum(sum[31:16])
    );
    
endmodule

其实从做这个题目开始有点发觉就是通过代码来进行模拟的数字电路连接了,对线路点明明,用代码接线之类的。

adder2

HDLbits第四天
module fadd

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//

    wire cout0;
    wire cout1;
    
    add16 u1_add16(
        .a(a[15:0]),
        .b(b[15:0]),
        .cin(1'b0),
        .cout(cout0),
        .sum(sum[15:0])
    );
    
    add16 u2_add16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(cout0),
        .cout(cout1),
        .sum(sum[31:16])
    );
    
endmodule

module add1 ( input a, input b, input cin,   output sum, output cout );

    assign sum = a ^ b ^ cin;
    assign cout = (a & b) | (cin & (a ^ b));
    
endmodule

实际上这个题目的有两个目的一个是为了模块的组合,另一个是理解了全加法器的逻辑描述,可以使用数电的真值表进行逻辑代码的描写。

Carry-select adder

HDLbits第四天
Module cseladd

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cout0;
    wire cout1;
    wire cout2;
    wire [15:0]sum0;
    wire [15:0]sum1;
    
    add16 u1_add16(
        .a(a[15:0]),
        .b(b[15:0]),
        .cin(1'b0),
        .cout(cout0),
        .sum(sum[15:0])
    );
    
    add16 u2_add16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(1'b0),
        .cout(cout1),
        .sum(sum0[15:0])
    );
    
    add16 u3_add16(
    	.a(a[31:16]),
        .b(b[31:16]),
        .cin(1'b1),
        .cout(cout2),
        .sum(sum1[15:0])
    );
    
    assign sum[31:16] = cout0?sum1[15:0]:sum0[15:0];
    
endmodule

本题是为了加快计算的速度,与上一个题相比,上一个题中前一级的加法器没有运算完成,后面的加法器是无法进行计算的,而在这一个题目中,我们可以看到计算是同时进行的,同时将低位的加法器进位作为一个使能端,来选择是否需要高位的进位计算。通过这样的方法,可以加快一倍的运算速度,但是同时需要牺牲的资源也增加,所以需要根据具体的情况进行判断使用。

Adder-substractor

HDLbits第四天
module addsub

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);

    wire cout0;
    wire cout1;
    wire [31:0] b_n;
    
    assign b_n = b ^ {32{sub}};
    
    add16 u1_add16(
        .a(a[15:0]),
        .b(b_n[15:0]),
        .cin(sub),
        .cout(cout0),
        .sum(sum[15:0])
    );
    
    add16 u2_add16(
        .a(a[31:16]),
        .b(b_n[31:16]),
        .cin(cout0),
        .cout(cout1),
        .sum(sum[31:16])
    );
    
endmodule

在计算机中实际上存储的都是数据的补码,对于正数来说它的补码是自己本身,而对于一个复数来说它的补码是原码除了符号位之外取反然后加一。本题中就利用了这种思想构造了一个加减器,通过sub来控制计算器是加法还是减法,也就是将b作为正数处理还是作为负数处理。

程序员灯塔
转载请注明原文链接:HDLbits第四天
喜欢 (0)
违法和不良信息举报电话:022-22558618 举报邮箱:dljd@tidljd.com