HDLbits day5
三、Circuits
Combinational Logic
1、Basic gates
1.1、Wire
实现以下电路:
module top_module ( input in, output out); assign out = in; endmodule
1.2、GND
实现以下电路:
module top_module ( output out); always@(*) out = 1'b0; endmodule
1.3、NOR
实现以下电路:
module top_module ( input in1, input in2, output out); assign out = ~(in1|in2); endmodule
1.4、Another gate
实现以下电路:
module top_module ( input in1, input in2, output out); assign out = in1&(~in2); endmodule
1.5、Two gates
实现以下电路:
module top_module ( input in1, input in2, input in3, output out); wire w; assign w = in1~^in2; assign out = w^in3; endmodule
1.6、More logic gates
构建具有两个输入a和b的组合电路。有 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
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
1.7、7420 chip
7420 是具有两个 4 输入与非门的芯片。创建一个与 7420 芯片功能相同的模块。它有 8 个输入和 2 个输出。
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
1.8、Truth tables
创建一个实现下述真值表的组合电路。
module top_module( input x3, input x2, input x1, // three inputs output f // one output ); assign f=(~x3)&x2&(~x1)|(~x3)&x2&x1|x1&(~x2)&x3|x1&x2&x3; endmodule
1.9、Two-bit equality
创建一个具有两个 2 位输入A[1:0]和B[1:0]的电路,并产生一个输出z。如果A = B ,则z的值应为 1 ,否则z应为 0。
module top_module ( input [1:0] A, input [1:0] B, output z ); always@(*) begin if(A==B) z=1; else z=0; end endmodule
1.10、Simple circuit A
模块 A 应该实现函数z = (x^y) & x。实现这个模块。
module top_module (input x, input y, output z); assign z=(x^y)&x; endmodule
1.11、Simple circuit B
电路B可以用下面的仿真波形来描述:
实现这个电路。
module top_module ( input x, input y, output z ); assign z=x~^y; endmodule
1.12、Combine circuits A and B
顶层设计由子电路 A 和 B 的两个实例组成,如下所示。
实现这个电路。
module top_module (input x, input y, output z); wire w1,w2,w3,w4,w5,w6; assign w1=(x^y)&x,w2=(x^y)&x; assign w3=x~^y,w4=x~^y; assign w5=w1|w2,w6=w3&w4; assign z=w5^w6; endmodule
1.13、Ring or vibrate?
假设您正在设计一个电路来控制手机的振铃器和振动电机。每当电话需要从来电中振铃 ( ) 时,您的电路必须打开振铃器 ( ) 或电机 ( ),但不能同时打开两者。如果手机处于振动模式 ( ),请打开电机。否则,打开铃声。尝试仅使用assign
语句,看看您是否可以将问题描述转换为逻辑门的集合。
ring | vibrate_mode | ringer | motor |
0 | 0 | 0 | 0 |
0 | 1 | 0 | 0 |
1 | 0 | 1 | 0 |
1 | 1 | 1 | 1 |
module top_module ( input ring, input vibrate_mode, output ringer, // Make sound output motor // Vibrate ); assign ringer=ring&(~vibrate_mode); assign motor=ring&vibrate_mode; endmodule
1.14、Thermostat
加热/冷却恒温器控制加热器(冬季)和空调(夏季)。实施一个可以根据需要打开和关闭加热器、空调和鼓风机的电路。
恒温器可以处于以下两种模式之一:加热 ( mode = 1
) 和冷却 ( mode = 0
)。在制热模式下,当天气太冷时打开加热器(too_cold = 1
),但不要使用空调。在制冷模式下,空调过热时打开空调(too_hot = 1
),但不要打开加热器。当加热器或空调打开时,还要打开风扇以循环空气。此外,fan_on = 1
即使加热器和空调已关闭,用户也可以请求打开风扇 ( )。
尝试仅使用assign
语句,看看您是否可以将问题描述转换为逻辑门的集合。
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&(~aircon); assign aircon=(~mode)&too_hot&(~heater); assign fan=fan_on|heater|aircon; endmodule
1.15、3-bit population count
“人口计数”电路计算输入向量中“1”的数量。为 3 位输入向量构建人口计数电路。
module top_module( input [2:0] in, output [1:0] out ); reg[1:0] i; always@(*) begin out=2'b00; for(i=2'b00;i<=2'b10;i=i+2'b01) //在用reg变量做for循环计数时,还要考虑i赋值的宽度,不能直接1=1;i<=2;i=i+1 begin if(in[i]==3'b001) out=out+2'b01; else out=out+2'b00; end end endmodule
1.16、Gates and vectors
在 [3:0] 中给定一个四位输入向量。我们想知道每个位与其邻居之间的一些关系:
- out_both:此输出向量的每个位都应指示相应的输入位及其左侧的邻居(较高的索引)是否都是“1” 。例如,out_both[2]应该表明in[2]和in[3]是否都为 1。由于in[3]左边没有邻居,所以答案很明显,所以我们不需要知道out_both[3 ] .
- out_any:此输出向量的每个位应指示相应的输入位及其右侧的邻居是否为“1”。例如,out_any[2]应该指示in[2]或in[1]是否为 1。由于in[0]右侧没有邻居,因此答案很明显,因此我们不需要知道out_any[0 ] .
- out_different:此输出向量的每个位都应指示相应的输入位是否与其左侧的邻居不同。例如,out_diff[2]应该指示in[2]是否与in[3]不同。对于这部分,将向量视为环绕,因此in[3]左侧的邻居是in[0]。
module top_module( input [3:0] in, output [2:0] out_both, output [3:1] out_any, output [3:0] out_different ); integer i; always@(*) begin for(i=0;i<=2;i=i+1) if(in[i]==1&in[i+1]==1) out_both[i]=1; else out_both[i]=0; for(i=1;i<=3;i=i+1) if(in[i]==1|in[i-1]==1) out_any[i]=1; else out_any[i]=0; for(i=0;i<=2;i=i+1) if(in[i]^in[i+1]) out_different[i]=1; else out_different[i]=0; end assign out_different[3]=in[3]^in[0]; endmodule
1.17、Even longer vectors
在 [99:0] 中给定一个 100 位的输入向量。我们想知道每个位与其邻居之间的一些关系:
- out_both:此输出向量的每个位应指示相应的输入位及其左侧的邻居是否都为“1”。例如,out_both[98]应该表明in[98]和in[99]是否都是 1。由于in[99]左边没有邻居,答案很明显,所以我们不需要知道out_both[99 ] .
- out_any:此输出向量的每个位应指示相应的输入位及其右侧的邻居是否为“1”。例如,out_any[2]应该指示in[2]或in[1]是否为 1。由于in[0]右侧没有邻居,因此答案很明显,因此我们不需要知道out_any[0 ] .
- out_different:此输出向量的每个位都应指示相应的输入位是否与其左侧的邻居不同。例如,out_diff[98]应该指示in[98]是否与in[99]不同。对于这部分,将向量视为环绕,因此in[99]左侧的邻居是in[0]。
module top_module( input [99:0] in, output [98:0] out_both, output [99:1] out_any, output [99:0] out_different ); integer i; always@(*) begin for(i=0;i<=98;i=i+1) if(in[i]==1&in[i+1]==1) out_both[i]=1; else out_both[i]=0; for(i=1;i<=99;i=i+1) if(in[i]==1|in[i-1]==1) out_any[i]=1; else out_any[i]=0; for(i=0;i<=98;i=i+1) if(in[i]^in[i+1]) out_different[i]=1; else out_different[i]=0; end assign out_different[99]=in[98]^in[0]; endmodule