HDLBits——Basic Gates
Problem 43 Wire
Requirement:
实现如下电路:
Solution:
module top_module (
input in,
output out);
assign out = in;
endmodule
PS:一个简单的 wire 型输出,直接 assign 即可。
Problem 44 GND
Requirement:
实现如下电路:
Solution:
module top_module (
output out);
assign out = 1'b0;
endmodule
Problem 45 NOR
Requirement:
实现如下电路:
Solution:
module top_module (
input in1,
input in2,
output out);
assign out = ~(in1 | in2);
endmodule
Problem 46 Another gate
Requirement:
Solution:
module top_module (
input in1,
input in2,
output out);
assign out = in1 & (~in2);
endmodule
Problem 47 Two gates
Requirement:
Solution:
module top_module (
input in1,
input in2,
input in3,
output out);
assign out = in3 ^ ~(in1 ^ in2);
endmodule
PS:也可以先声明一个 wire 型的 temp 来存放同或门的输出。
Problem 48 More logic gates
Requirement:
用两输入的组合电路来实现如下功能,该电路共有 7 个输出,每个输出都有一个逻辑门驱动它:
- out_and: a and b
- out_or: a or b
- out_xor: a xor b
- out_nand: a nand b
- out_nor: a nor b
- out_xnor: a xnor b
- out_anotb: a and-not b
Solution:
module top_module(
input a, b,
output out_and,
output out_or,
output out_xor,
output out_nand,
output out_nor,
output out_xnor,
output out_anotb
);
assign out_and = a & b;
assign out_or = a | b;
assign out_xor = a ^ b;
assign out_nand = ~(a & b);
assign out_nor = ~(a | b);
assign out_xnor = ~(a ^ b);
assign out_anotb = a & (~b);
endmodule
Timing Diagram:
Problem 49 : 7420 chip
Requirement:
7420 chip 是拥有两组 4 输入的与非门芯片,本练习需要构造一个与 7420 chip 功能一样的电路,拥有 8 个输入与 2 个输出。
Solution:
module top_module (
input p1a, p1b, p1c, p1d,
output p1y,
input p2a, p2b, p2c, p2d,
output p2y );
assign p1y = ~(p1a & p1b & p1c &p1d);
assign p2y = ~(p2a & p2b & p2c &p2d);
endmodule
Timing Diagram:
Problem 50 Truth tables 真值表
Requirement:
组合意味着电路的输出只是其输入的函数(在数学意义上),也就是说对于任何给定的输入值,只有一个可能的输出值。因此,描述组合函数行为的一种方法是明确列出每个可能值的输入值及其对应的输出。这就是真值表。
采用最小项之和的方法来构建电路图,最小项表达式为真值表中每一个对应函数值为 1 的输入变量,将上图真值表中函数值为 1 的最小项取出相加,便是函数最小项表达式。
创建一个实现上述真值表的组合电路。
Solution:
module top_module(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
assign f = (~x3)&x2 | x3&x1;
endmodule
错过:化简后如下,可别把乘号和加号写成 * 和 +,其含义应该是 & 和 |。
f
=
x
3
ˉ
x
2
+
x
3
x
1
f = \bar{x3}x2+x3x1
f=x3ˉx2+x3x1
Timing Diagram:
Problem 51 Two-bit equality
Requirement:
两输入 A [1:0], B[1:0],一输出Z,当A 与 B 相等时,Z 输出为1, 否则为0;
Solution:
module top_module ( input [1:0] A, input [1:0] B, output reg z );
always @(*) begin
if (A == B) begin
z = 1;
end
else begin
z = 0;
end
end
endmodule
注意:异或,同或都针对一位,多位要用 == 来检查。
Problem 52 Simple circuit A
Requirement:
创建一个电路,其功能可以实现 z = (x ^ y) & x。
Solution:
module top_module (input x, input y, output z);
assign z = (x ^ y) & x;
endmodule
Problem 53 Simple circuit B
Requirement:
根据仿真时序图创建电路B。
Solution:
module top_module (input x, input y, output z);
assign z = ~(x ^ y);
endmodule
PS:时序图——>真值表——>电路图
Timing Diagram:
Problem 54 Combine circuits A and B
Requirement:
根据子模块Problem 53 与 52 来实现如下电路:
PS:
Problem 52 Simple circuit A:z = (x ^ y) & x
Problem 53 Simple circuit B:z = x ^~ y
Solution:
module top_module (input x, input y, output z);
wire w1,w2;
assign w1 = (x ^ y) & x;
assign w2 = x ^~ y;
assign z = (w1&w2)^(w1|w2);
endmodule
注意:虽然结果一样,但这样写对应的图(电路)就不是题目所给的了,少了两个门。
方法二:按照题目要求,例化子模块。
module top_module (input x, input y, output z);
wire w1,w2,w3,w4;
A IA1(x,y,w1);
A IA2(x,y,w3);
B IB1(x,y,w2);
B IB2(x,y,w4);
assign z = (w1 | w2) ^ (w3 & w4);
endmodule
module A (
input x,
input y,
output z);
assign z = (x^y) & x;
endmodule
module B (
input x,
input y,
output z);
assign z = ~(x^y);
endmodule
Problem 55 Ring or vibrate
Requirement:
设计一个电路来控制手机的振铃器和振动电机,当手机来电时(input ring),电路必须把震动( output motor = 1 )或响铃( output ringer = 1 )打开,但不能同时打开。当手机处于震动模式时( input vibrate = 1 ),则打开震动( output motor = 1 ),否则打开响铃。请仅使用 assign 语句来实现该组合电路。
Solution:
module top_module (
input ring,
input vibrate_mode,
output ringer, // Make sound
output motor // Vibrate
);
assign motor = ring & vibrate_mode;
assign ringer = ring & ~(vibrate_mode);
endmodule
注意:硬件编程和软件编程的设计思路是有差别的,软件是先关注输入,也就是在各种情况下分别输出什么。硬件是先关注输出,输出某值时其输入有哪几种(也就是在表达之前先化简卡诺图的步骤)。
Timing Diagram:
Problem 56 Thermostat
Requirement:
一个冷/热恒温控制器可以同时在冬季和夏季对温度进行调节。设计一个电路,根据需要打开和关闭加热器、空调和鼓风机风扇。恒温器可以处于两种模式之一:制热(mode = 1)和制冷(mode = 0)。在制热模式下,当温度过低时(too_cold = 1),打开加热器,但不要使用空调。在制冷模式下,当温度过高(too_hot = 1)打开空调,但不要打开加热器。当加热器或空调打开时,也打开风扇使空气循环。此外,即使加热器和空调关闭,用户也可以请求将风扇打开(fan_on = 1)。尝试仅使用assign语句来设计该电路。
Solution:
module top_module (
input too_cold,
input too_hot,
input mode,
input fan_on,
output heater,
output aircon,
output fan
);
assign heater = mode & too_cold;
assign aircon = ~mode & too_hot;
assign fan = (mode & too_cold) | (~mode & too_hot) | fan_on;
endmodule
PS:遇到描述很复杂的电路时,先列真值表(不用列出所有情况,列出题上有的就行),然后化简,接着写表达式,就欧了。
改进:assign fan = heater | aircon | fan_on;
Timing Diagram:
Problem 57 3-bit population count
Requirement:
设计一个电路来计算输入中 ‘ 1 ’ 个数。
Solution:
module top_module(
input [2:0] in,
output reg [1:0] out );
integer i;
always @(*) begin
out = 2'b0;
for(i=0;i<3;i=i+1) begin
if(in[i]==1'b1) out = out + 1;
else out = out + 0;
end
end
endmodule
改进:assign out = in[0] + in[1] + in[2];
Timing Diagram:
Problem 58 Gates and vectors
Requirement:
有一个 4bit 输入的电路,关系如下:
-
out_both: 输入的每一个 bit 均需要检测该 bit 位与其左侧(即高比特位)是否全为 ‘ 1 ’ 。
示例: out_both[2] 应检测 in[2] 与 in[3] 是否均为 ‘ 1 ’ 。in[3] 为输入的最高位,无需out_both[3]。
-
out_any: 输入的每一个 bit 均需要检测该 bit 位与其右侧(即低比特位)两者其中一个是否为 ‘ 1 ’ 。
示例: out_any[2] 应检测 in[2] 与 in[1] 两者其中一个为 ‘ 1 ’ 。in[0] 为输入的最低位,无需 out_any[0]。
-
out_different: 输入的每一个 bit 均需要检测该 bit 位与其左侧(即高比特位)两者是否不同。 示例: out_different[2] 应检测 in[2] 与 in[3] 两者是否不同 ,将输入变成一个环,所以 in[3] 的左侧为 in[0]。
Solution:
module top_module(
input [3:0] in,
output reg [2:0] out_both,
output reg [3:1] out_any,
output reg [3:0] out_different );
integer i;
always @(*) begin
for (i = 0; i<=3; i=i+1) begin
if(i != 3) out_both[i] = in[i] & in[i+1];
if(i != 0) out_any[i] = in[i] | in[i-1];
if(i != 3) out_different[i] = in[i] ^ in[i+1];
end
out_different[3] = in[3] ^ in[0];
end
endmodule
改进:&、|、^ 是按位运算符。
assign out_both = in[2:0] & in[3:1];
assign out_any = in[3:1] | in[2:0];
assign out_different = in ^ {in[0], in[3:1]};
Timing Diagram:
Problem 59 Even longer vectors
Requirement:
与 Problem 59 类似,仅将输入从 4bit 改为 100bit ( input [99:0] ),题目的其余要求均相同。
Solution:
module top_module(
input [99:0] in,
output [98:0] out_both,
output [99:1] out_any,
output [99:0] out_different );
assign out_both = in[98:0] & in[99:1];
assign out_any = in[98:0] | in[99:1];
assign out_different = in[99:0] ^ {in[0],in[99:1]};
endmodule
PS:和相邻位进行比较,可以用移位的思想。
PS:学会一个新技能,彩色的字。
<font color=red>红色</font>
这部分虽然题很多,但都很简单。