出于对FPGA学习巩固的目的,同时也希望能锻炼自己对于Verilog的题目分析,让自己对HDL代码的理解加深,所以想坚持写一下关于HDLbits网站刷题的系列,计划是工作日每日5题目+分析,周末每日十题+分析(如果题目繁琐会减轻数量,以能够分析准确并理解为主)
Verilog Language
Modules: Hierarchy
adder1
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
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
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
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作为正数处理还是作为负数处理。
标签:15,HDLbits,31,16,add16,第四天,input,sum From: https://www.cnblogs.com/havi/p/16925615.html