3.1.1.12 Ring or vibrate
问题陈述:
假设您正在设计一个电路来控制手机的振铃器和振动电机。每当电话需要从来电中振铃 ( input ring) 时,您的电路必须打开振铃器 ( output ringer = 1) 或电机 ( output motor= 1),但不能同时打开两者。如果手机处于振动模式 (input vibrate_mode = 1 ),请打开电机。否则,打开铃声。
尝试仅使用assign语句,看看您是否可以将问题描述转换为逻辑门的集合。
verilog代码:
module top_module (
input ring,
input vibrate_mode,
output ringer, // Make sound
output motor // Vibrate
);
assign ringer=(ring&&!vibrate_mode)?2'd1:2'd0;
assign motor=(vibrate_mode&&ring)?2'd1:2'd0;
endmodule
ring=1,vibrate_mode=0 =>ringter=1,打开振铃器;
ring=1,vibrate_mode=1 =>,mode=1,打开电机;
3.1.1.13 Thermostat
问题陈述:
加热/冷却恒温器控制加热器(冬季)和空调(夏季)。实施一个可以根据需要打开和关闭加热器、空调和鼓风机的电路。
恒温器可以处于以下两种模式之一:加热 ( mode = 1) 和冷却 ( mode = 0)。在制热模式下,当天气太冷时打开加热器(too_cold = 1),但不要使用空调。在制冷模式下,空调过热时打开空调(too_hot =1),但不要打开加热器。当加热器或空调打开时,还要打开风扇以循环空气。此外,即使加热器和空调已关闭,用户也可以请求打开风扇 ( fan_on= 1)。
尝试仅使用assign语句,看看您是否可以将问题描述转换为逻辑门的集合。
Verilog代码:
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==1)?1:0;
assign aircon=(~mode&&too_hot==1)?1:0;
assign fan=((mode&&too_cold)||(~mode&&too_hot)||fan_on==1)?1:0;
endmodule
mode=1,too_cold=1=>heater=1;
mode=0,too_hot=1=>aircon=1;
上面两种情况,还有fan_on=1 =>fan=1.
3.1.1.14 3-bit population count
问题陈述:
人口计数”电路计算输入向量中“1”的数量。为 3 位输入向量构建人口计数电路。
Verilog代码:
module top_module(
input [2:0] in,
output [1:0] out );
assign out=in[0]+in[1]+in[2];
endmodule
3.1.1.15 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]。
verilog代码:
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<3;i++)
begin
out_both[i]=in[i+1]&in[i];
end
end
always @(*)
begin
for(i=3;i>0;i--)
begin
out_any[i]=in[i]|in[i-1];
end
end
assign out_different={{in[3]^in[0]},{in[2]^in[3]},{in[1]^in[2]},{in[0]^in[1]}};
endmodule
判断是否都为“1”,与左侧的相与即可判断出;判断其中一个是否为“1”,与右侧的数相或即可判断出;判断两个数是否相同,两个数XOR,若为“1”则两数相同,若为“0”则两数不同。
方法2:
module top_module(
input [3:0] in,
output [2:0] out_both,
output [3:1] out_any,
output [3:0] out_different );
assign out_both=in[2:0]&in[3:1];
assign out_any=in[3:1]|in[2:0];
assign out_different={{in[3]^in[0]},{in[2]^in[3]},{in[1]^in[2]},{in[0]^in[1]}};
endmodule
3.1.1.16 Even longer vector
问题陈述:
在 [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]。
Verilog代码:
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[99:1]|in[98:0];
assign out_different=in^{in[0],in[99:1]};
endmodule