本节是一些练习巩固的习题。
Wire
Solution
module top_module (
input in,
output out);
assign out = in;
endmodule
GND
GND(Ground): “地线” 或 “接地”。
Solution
module top_module (
output out);
assign out = 1'b0;
endmodule
NOR
Solution
module top_module (
input in1,
input in2,
output out);
assign out = ~(in1 | in2); //注意别忘了“非”
endmodule
Another gate
Solution
module top_module (
input in1,
input in2,
output out);
assign out = in1 & ~in2;
endmodule
Two gates
Solution
module top_module (
input in1,
input in2,
input in3,
output out);
wire m1;
assign m1 = ~(in1 ^ in2);
assign out = m1 ^ in3;
endmodule
More logic gates
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; //a 和 非b
endmodule
7420 chip
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
Truth tables
One simple method to create a circuit that implements the truth table's function is to express the function in sum-of-products form. Sum (meaning OR) of products (meaning AND) means using one N-input AND gate per row of the truth table (to detect when the input matches each row), followed by an OR gate that chooses only those rows that result in a '1' output.
总结:推导 sum-of-products (SOP,积之和)的核心逻辑:
用最小项 “标记” 所有输出为 1 的输入组合,再用 OR 运算 “汇总” 这些有效组合。由于最小项仅在唯一输入组合下为 1,OR 之后的表达式能精准复现真值表的输出逻辑。
“找 1 行,写反 / 原变量乘积,再 OR”。
Solution
module top_module(
input x3,
input x2,
input x1, // three inputs
output f // one output
);
assign f = (~x3 & x2 & ~x1) | (~x3 & x2 & x1) | (x3 & ~x2 & x1) | (x3 & x2 & x1);
endmodule
Two-bit equality
通过直接比较两个 2 位输入 A 和 B 来判断它们是否相等,采用了 Verilog 的条件赋值语句即可。
Solution
module top_module ( input [1:0] A, input [1:0] B, output z );
assign z = (A == B) ? 1'b1 : 1'b0;
endmodule
Simple circuit A
Solution
module top_module (input x, input y, output z);
assign z = (x ^ y) & x;
endmodule
Simple circuit B
先列出真值表:
input: x | input: y | output: z |
---|---|---|
0 | 0 | 1 |
1 | 0 | 0 |
0 | 1 | 0 |
1 | 1 | 1 |
Solution
module top_module ( input x, input y, output z );
assign z = (~x & ~y) | (x & y);
endmodule
Combine circuits A and B
Solution
module top_module (input x, input y, output z);
wire z1,z2,z3,z4;
moduleA u1 (.x(x), .y(y), .z(z1)); //通过实例化可以用A模块获得 z1
moduleB u2 (.x(x), .y(y), .z(z2));
moduleA u3 (.x(x), .y(y), .z(z3));
moduleB u4 (.x(x), .y(y), .z(z4));
wire m1,m2;
assign m1 = z1 | z2;
assign m2 = z3 & z4;
assign z = m1 ^ m2;
endmodule
//module之间是并行的,所以不需要提前声明。
module moduleA (input x, input y, output z);
assign z = (x ^ y) & x;
endmodule
module moduleB ( input x, input y, output z );
assign z = (~x & ~y) | (x & y);
endmodule
Ring or vibrate?
响铃还是震动?
When designing circuits, one often has to think of the problem "backwards", starting from the outputs then working backwards towards the inputs. This is often the opposite of how one would think about a (sequential, imperative) programming problem, where one would look at the inputs first then decide on an action (or output). For sequential programs, one would often think "If (inputs are --- ) then (output should be --- )". On the other hand, hardware designers often think "The (output should be ---) when (inputs are ---)".
Solution
module top_module (
input ring,
input vibrate_mode,
output ringer, // Make sound
output motor // Vibrate
);
//assign ringer = (ring ? 1'b1 : 1'b0); //Error
//assign motor = (vibrate_mode ? 1'b1 : 1'b0); //Error
assign ringer = ring & ~vibrate_mode; //有来电,且没有设置为震动模式时响铃
assign motor = ring & vibrate_mode; //有来电,且有设置为震动模式时震动
endmodule
Thermostat
Solution
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 = too_cold | too_hot | fan_on; //Logic Error
assign fan = heater | aircon | fan_on;
endmodule
3-bit population count
Solution
module top_module(
input [2:0] in,
output [1:0] out );
integer i;
always @(*) begin
out = 2'b00;
for (i = 0; i < 3; i++) begin
if(in[i] == 1'b1)
out = out + 1;
end
end
endmodule
Gates and vectors
Solution
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] & in[i + 1];
end
for(i = 1; i < 4; i++) begin
out_any[i] = in[i] | in[i - 1];
end
for(i = 0; i < 4; i++) begin
if(i == 3)
out_different[3] = in[3] ^ in[0];
else
out_different[i] = in[i] ^ in[i + 1];
end
end
endmodule
Even longer vectors
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 < 99; i++) begin
out_both[i] = in[i] & in[i + 1];
end
for(i = 1; i < 100; i++) begin
out_any[i] = in[i] | in[i - 1];
end
for(i = 0; i < 100; i++) begin
if(i == 99)
out_different[99] = in[99] ^ in[0];
else
out_different[i] = in[i] ^ in[i + 1];
end
end
endmodule