Verilog语言 Circuits第一章 basic gates练习题
题目1:
See mt2015_q4a and mt2015_q4b for the submodules used here. The top-level design consists of two instantiations each of subcircuits A and B, as shown below.
其中A模块和B模块前面题目都有写到,
A模块的逻辑表达式为:z = (x ^ y) & x;
B模块的逻辑表达式为:z = ~(x^y);
我的解答:
module top_module (input x, input y, output z);
wire zIA1,zIB1,zIA2,zIB2;
wire zor,zand;
A ia1(
.x(x),
.y(y),
.z(zIA1)
);
B ib1(
.x(x),
.y(y),
.z(zIB1)
);
A ia2(
.x(x),
.y(y),
.z(zIA2)
);
B ib2(
.x(x),
.y(y),
.z(zIB2)
);
assign zor = zIA1|zIB1;
assign zand = zIA2&zIB2;
assign z = zor^zand;
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
题目2:
Suppose you are designing a circuit to control a cellphone’s ringer and vibration motor. Whenever the phone needs to ring from an incoming call (input ring), your circuit must either turn on the ringer (output ringer = 1) or the motor (output motor = 1), but not both. If the phone is in vibrate mode (input vibrate_mode = 1), turn on the motor. Otherwise, turn on the ringer.
Try to use only assign statements, to see whether you can translate a problem description into a collection of logic gates.
分析:逻辑问题,画真值表即可。
根据真值表,再用assign语句赋值,便能实现该电路。
我的解答:
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
题目3:
A heating/cooling thermostat controls both a heater (during winter) and an air conditioner (during summer). Implement a circuit that will turn on and off the heater, air conditioning, and blower fan as appropriate.
The thermostat can be in one of two modes: heating (mode = 1) and cooling (mode = 0). In heating mode, turn the heater on when it is too cold (too_cold = 1) but do not use the air conditioner. In cooling mode, turn the air conditioner on when it is too hot (too_hot = 1), but do not turn on the heater. When the heater or air conditioner are on, also turn on the fan to circulate the air. In addition, the user can also request the fan to turn on (fan_on = 1), even if the heater and air conditioner are off.
Try to use only assign statements, to see whether you can translate a problem description into a collection of logic gates.
画出真值表:
我的解答:
module top_module (
input too_cold,
input too_hot,
input mode,
input fan_on,
output heater,
output aircon,
output fan
);
assign heater = too_cold & mode ;
assign aircon = too_hot & (~mode);
assign fan = fan_on | heater | aircon;
endmodule
题目4:
A “population count” circuit counts the number of '1’s in an input vector. Build a population count circuit for a 3-bit input vector.
我的解答:
module top_module(
input [2:0] in,
output [1:0] out );
always @(*)begin
case(in)
3'd0 : out = 2'd0;
3'd1 : out = 2'd1;
3'd2 : out = 2'd1;
3'd3 : out = 2'd2;
3'd4 : out = 2'd1;
3'd5 : out = 2'd2;
3'd6 : out = 2'd2;
3'd7 : out = 2'd3;
endcase
end
endmodule
看到的另一种解答方法:
module top_module(
input [2:0] in,
output [1:0] out );
always @(*) begin
out = 0;
for (int i=0;i<3;i++)
out = out + in[i];
end
endmodule
官方solution:
module top_module (
input [2:0] in,
output [1:0] out
);
// This is a function of 3 inputs. One method is to use a 8-entry truth table:
// in[2:0] out[1:0]
// 000 00
// 001 01
// 010 01
// 011 10
// 100 01
// 101 10
// 110 10
// 111 11
assign out[0] = (~in[2] & ~in[1] & in[0]) | (~in[2] & in[1] & ~in[0]) | (in[2] & ~in[1] & ~in[0]) | (in[2] & in[1] & in[0]);
assign out[1] = (in[1] & in[0]) | (in[2] & in[0]) | (in[2] & in[1]);
// Using the addition operator works too:
// assign out = in[0]+in[1]+in[2];
// Yet another method uses behavioural code inside a procedure (combinational always block)
// to directly implement the truth table:
/*
always @(*) begin
case (in)
3'd0: out = 2'd0;
3'd1: out = 2'd1;
3'd2: out = 2'd1;
3'd3: out = 2'd2;
3'd4: out = 2'd1;
3'd5: out = 2'd2;
3'd6: out = 2'd2;
3'd7: out = 2'd3;
endcase
end
*/
endmodule
题目5:
You are given a four-bit input vector in[3:0]. We want to know some relationships between each bit and its neighbour:
out_both: Each bit of this output vector should indicate whether both the corresponding input bit and its neighbour to the left (higher index) are ‘1’. For example, out_both[2] should indicate if in[2] and in[3] are both 1. Since in[3] has no neighbour to the left, the answer is obvious so we don’t need to know out_both[3].
out_any: Each bit of this output vector should indicate whether any of the corresponding input bit and its neighbour to the right are ‘1’. For example, out_any[2] should indicate if either in[2] or in[1] are 1. Since in[0] has no neighbour to the right, the answer is obvious so we don’t need to know out_any[0].
out_different: Each bit of this output vector should indicate whether the corresponding input bit is different from its neighbour to the left. For example, out_different[2] should indicate if in[2] is different from in[3]. For this part, treat the vector as wrapping around, so in[3]'s neighbour to the left is in[0].
提示:
The both, any, and different outputs use two-input AND, OR, and XOR operations, respectively. Using vectors, this can be done in 3 assign statements.
我的解答:
module top_module(
input [3:0] in,
output [2:0] out_both,
output [3:1] out_any,
output [3:0] out_different );
always@(*)begin
for(int i=3;i>0;i--)
out_both[i-1] = in[i] & in[i-1];
end
always@(*)begin
for(int i=0;i<3;i++)
out_any[i+1] = in[i]|in[i+1];
end
always@(*)begin
for(int i=3;i>0;i--)
out_different[i-1] = in[i]^in[i-1];
out_different[3] = in[3]^in[0];
end
endmodule
官方solution:
module top_module (
input [3:0] in,
output [2:0] out_both,
output [3:1] out_any,
output [3:0] out_different
);
// Use bitwise operators and part-select to do the entire calculation in one line of code
// in[3:1] is this vector: in[3] in[2] in[1]
// in[2:0] is this vector: in[2] in[1] in[0]
// Bitwise-OR produces a 3 bit vector. | | |
// Assign this 3-bit result to out_any[3:1]: o_a[3] o_a[2] o_a[1]
// Thus, each output bit is the OR of the input bit and its neighbour to the right:
// e.g., out_any[1] = in[1] | in[0];
// Notice how this works even for long vectors.
assign out_any = in[3:1] | in[2:0];
assign out_both = in[2:0] & in[3:1];
// XOR 'in' with a vector that is 'in' rotated to the right by 1 position: {in[0], in[3:1]}
// The rotation is accomplished by using part selects[] and the concatenation operator{}.
assign out_different = in ^ {in[0], in[3:1]};
//这一块为了满足题目要求,将in的高位也就是in[3]和in[0]用位拼接符单独提出后进行异或,其余
//的位不变
endmodule
题目6:
You are given a 100-bit input vector in[99:0]. We want to know some relationships between each bit and its neighbour:
out_both: Each bit of this output vector should indicate whether both the corresponding input bit and its neighbour to the left are ‘1’. For example, out_both[98] should indicate if in[98] and in[99] are both 1. Since in[99] has no neighbour to the left, the answer is obvious so we don’t need to know out_both[99].
out_any: Each bit of this output vector should indicate whether any of the corresponding input bit and its neighbour to the right are ‘1’. For example, out_any[2] should indicate if either in[2] or in[1] are 1. Since in[0] has no neighbour to the right, the answer is obvious so we don’t need to know out_any[0].
out_different: Each bit of this output vector should indicate whether the corresponding input bit is different from its neighbour to the left. For example, out_different[98] should indicate if in[98] is different from in[99]. For this part, treat the vector as wrapping around, so in[99]'s neighbour to the left is in[0].
提示:Using vectors, this can still be done in 3 assign statements.
我的解答:
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 & in[99:1];
assign out_any = in[99:1] | in ;
assign out_different = in ^ {in[0], in[99:1]};
endmodule
官方solution:
module top_module (
input [99:0] in,
output [98:0] out_both,
output [99:1] out_any,
output [99:0] out_different
);
// See gatesv for explanations.
assign out_both = in & in[99:1];
assign out_any = in[99:1] | in ;
assign out_different = in ^ {in[0], in[99:1]};
endmodule