概述
60~71 多路选择器/加法器
- 60.Mux2to1
- 61.2-to-1 bus multiplexer (Mux2to1v)
- 62.9-to-1 multiplexer (Mux9to1v)
- 63.256-to-1 multiplexer (Mux256to1)
- 64.256-to-1 4-bit multiplexer (Mux256to1v)
- 65.Half adder(半加器)
- 66.Full adder(全加器)
- 67.3-bit binary adder
- 68.Adder-4-bit 全加器
- 69.Signed addition overflow(有符号数的进位问题)
- 70.100-bit binary adder
- 71.4-digit BCD adder
强烈建议大家去看看HDLBits 中文导学,原文在知乎
链接: link.
60.Mux2to1
assign out=sel?b:a;
61.2-to-1 bus multiplexer (Mux2to1v)
assign out=sel?b:a;
62.9-to-1 multiplexer (Mux9to1v)
module top_module(
input [15:0] a, b, c, d, e, f, g, h, i,
input [3:0] sel,
output [15:0] out );
always@(*)
case(sel)
4'd0:out = a;
4'd1:out = b;
4'd2:out = c;
4'd3:out = d;
4'd4:out = e;
4'd5:out = f;
4'd6:out = g;
4'd7:out = h;
4'd8:out = i;
default:out=16'b1111111111111111;
endcase
endmodule
答案中是先将所有的输出都赋值全为1,然后用到的再改
out = '1; // '1 is a special literal syntax for a number with all bits set to 1.
// '0, 'x, and 'z are also valid.
// I prefer to assign a default value to 'out' instead of using a
// default case
63.256-to-1 multiplexer (Mux256to1)
选择运算符的 index 可以为变量,只要变量的位宽和向量的长度匹配即可。
所以我们直接将 sel ,这个变量,作为片选向量 in 的 index。
assign out=in[sel];
64.256-to-1 4-bit multiplexer (Mux256to1v)
没写出来,直接看的解析
module top_module (
input [1023:0] in,
input [7:0] sel,
output [3:0] out
);
// We can't part-select multiple bits without an error, but we can select one bit at a time,
// four times, then concatenate them together.
assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};
// Alternatively, "indexed vector part select" works better, but has an unfamiliar syntax:
// assign out = in[sel*4 +: 4]; // Select starting at index "sel*4", then select a total width of 4 bits with increasing (+:) index number.
// assign out = in[sel*4+3 -: 4]; // Select starting at index "sel*4+3", then select a total width of 4 bits with decreasing (-:) index number.
// Note: The width (4 in this case) must be constant.
endmodule
大概的意思就是,不能一下子全都选了,但是可以,一次选择一位,选四次;没想到的8位输入的sel直接乘以4就和in的位宽一样了。
错误的语法:
assign out = in[ sel*4+3 : sel*4 ]; 但这个表达式不符合 Verilog 片选操作符的语法
片选多个比特的正确语法有两种:
assign out = in[sel*4 +: 4];// 从 sel*4 开始,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4]
assign out = in[sel*4+3 -: 4]; // 从 sel*4+3 开始,选择比特序号小于 sel*4+3 的 4 位比特,相当于[sel*4+3:sel*4]
65.Half adder(半加器)
半加:不考虑来自低位的进位将两个1位二进制数相加;
//assign {cout,sum} = a + b;
assign cout=a&b;
assign sum=(a&!b)|(!a&b);// assign sum=a^b;
66.Full adder(全加器)
全加器:将两个多位二进制数相加,除了最低位以外,每一位都应考虑来自低位的进位,即将两个对应位的加数和来自低位的进位三个数相加。
//assign{cout,sum} = a + b + cin;
assign cout=~((!a&!b)|(!b&!cin)|(!a&!cin));
assign sum=~((!a&!b&!cin)|(a&!b&cin)|(!a&b&cin)|(a&b&!cin));
67.3-bit binary adder
先用上面的连接的方法去写一下,
module top_module(
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
wire sum1,sum2,sum3,cout1,cout2,cout3;
assign{cout1,sum1}=a[0]+b[0]+cin;
assign{cout2,sum2}=a[1]+b[1]+cout1;
assign{cout3,sum3}=a[2]+b[2]+cout2;
assign cout={cout3,cout2,cout1};
assign sum={sum3,sum2,sum1};
endmodule
再用例化的方法
module top_module(
input [2:0] a, b,
input cin,
output [2:0] cout,
output [2:0] sum );
adder U1(
.a(a[0])
,.b(b[0])
,.cin(cin)
,.cout(cout[0])
,.sum(sum[0])
);
adder U2(
.a(a[1])
,.b(b[1])
,.cin(cout[0])
,.cout(cout[1])
,.sum(sum[1])
);
adder U3(
.a(a[2])
,.b(b[2])
,.cin(cout[1])
,.cout(cout[2])
,.sum(sum[2])
);
endmodule
module adder(
input a, b, cin,
output cout, sum );
assign{cout,sum} = a + b + cin;
)
endmodule
68.Adder-4-bit 全加器
先用例化的方法
module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum);
wire [3:0] cout;
fadd fa1(
.a(x[0]),
.b(y[0]),
.cin(),
.cout(cout[0]),
.sum(sum[0])
);
fadd fa2(
.a(x[1]),
.b(y[1]),
.cin(cout[0]),
.cout(cout[1]),
.sum(sum[1])
);
fadd fa3(
.a(x[2]),
.b(y[2]),
.cin(cout[1]),
.cout(cout[2]),
.sum(sum[2])
);
fadd fa4(
.a(x[3]),
.b(y[3]),
.cin(cout[2]),
.cout(cout[3]),
.sum(sum[3])
);
assign sum[4]=cout[3];
endmodule
module fadd(
input a, b, cin,
output cout, sum );
assign{cout,sum} = a + b + cin;
endmodule
看了答案,好像有更简单的方法
module top_module (
input [3:0] x,
input [3:0] y,
output [4:0] sum
);
// This circuit is a 4-bit ripple-carry adder with carry-out.
assign sum = x+y; // Verilog addition automatically produces the carry-out bit.
// Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands).
// This is correct:
// assign sum = (x+y);
// But this is incorrect:
// assign sum = {x+y}; // Concatenation operator: This discards the carry-out
endmodule
如果 x+y 产生了进位,verilog 的语法会自动将 x+y 扩展成 5 bit 数,如果使用位连接符 {x+y},那么结果就会被限制为 4 bit 数。
69.Signed addition overflow(有符号数的进位问题)
关于有符号数和无符号数的溢出情况可以看看这一篇link
有符号数的溢出情况分为两种:
- 正正相加,产生正溢出,
- 负负相减,产生负溢出;
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
70.100-bit binary adder
解除出问题其实很简单,再声明一个101位宽的sum1就行了,看了答案更简单;
module top_module(
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );
wire[100:0] sum1;
assign sum=a+b+cin;
assign sum1=a+b+cin;
assign cout=sum1[100];
//assign {cout, sum} = a+b+cin;
endmodule
但也可以例化一位全加器,使用generate语句或者for循环来写,就直接复制的自己没有写;
全加器模块,需要先写出来,例化的时候第一个需要单独处理。剩余的直接generate语句生成就可以了;
module top_module(
input [99:0] a, b,
input cin,
output cout,
output [99:0] sum );
wire [99:0] cout_temp;
//这还是将本次计算的cout当作下次计算的cin来使用
fadd inst1_fadd(
.a(a[0]),
.b(b[0]),
.cin(cin),
.cout(cout_temp[0]),
.sum(sum[0])
);
genvar i;
generate
for(i=1; i<100; i=i+1)
begin: add
//例化100次全加器
fadd inst2_fadd(
.a(a[i]),
.b(b[i]),
.cin(cout_temp[i-1]),
.cout(cout_temp[i]),
.sum(sum[i])
);
end
endgenerate
assign cout = cout_temp[99];
endmodule
module fadd (
input a, b, cin,
output sum, cout
);
assign {cout, sum} = a + b + cin;
//assign sum = a ^ b ^ cin;
// assign cout = a&b | a&cin | b&cin;
endmodule
71.4-digit BCD adder
module top_module(
input [15:0] a, b,
input cin,
output cout,
output [15:0] sum );
wire [3:0] cout_temp;
bcd_fadd bcd1(
.a(a[3:0]),
.b(b[3:0]),
.cin(cin),
.cout(cout_temp[0]),
.sum(sum[3:0]),
);
bcd_fadd bcd2(
.a(a[7:4]),
.b(b[7:4]),
.cin(cout_temp[0]),
.cout(cout_temp[1]),
.sum(sum[7:4]),
);
bcd_fadd bcd3(
.a(a[11:8]),
.b(b[11:8]),
.cin(cout_temp[1]),
.cout(cout_temp[2]),
.sum(sum[11:8]),
);
bcd_fadd bcd4(
.a(a[15:12]),
.b(b[15:12]),
.cin(cout_temp[2]),
.cout(cout_temp[3]),
.sum(sum[15:12]),
);
assign cout=cout_temp[3];
endmodule
最后
以上就是淡定哈密瓜为你收集整理的HDLBits刷题Day0760.Mux2to161.2-to-1 bus multiplexer (Mux2to1v)62.9-to-1 multiplexer (Mux9to1v)63.256-to-1 multiplexer (Mux256to1)64.256-to-1 4-bit multiplexer (Mux256to1v)65.Half adder(半加器)66.Full adder(全加器)67.3-bit binary adder68.Adder-4-bit 全加器69.Sig的全部内容,希望文章能够帮你解决HDLBits刷题Day0760.Mux2to161.2-to-1 bus multiplexer (Mux2to1v)62.9-to-1 multiplexer (Mux9to1v)63.256-to-1 multiplexer (Mux256to1)64.256-to-1 4-bit multiplexer (Mux256to1v)65.Half adder(半加器)66.Full adder(全加器)67.3-bit binary adder68.Adder-4-bit 全加器69.Sig所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复