目录
本篇博客对 Circuits 部分的组合逻辑前两节做答案和部分解析,一些比较简单的题目就直接给出答案,有些难度再稍作讲解,每道题的答案不一定唯一,可以有多种解决方案,欢迎共同讨论。
简单的逻辑实现
- module top_module (
- input in,
- output out
- );
- assign out = in;
- endmodule
对输出直接接地,言外之意就是将输出置0
- module top_module (
- output out
- );
- assign out = 1'b0;
- endmodule
实现或非门
- module top_module (
- input in1,
- input in2,
- output out
- );
- assign out = !(in1 | in2);
-
- endmodule
- module top_module (
- input in1,
- input in2,
- output out
- );
- assign out = (in1 & (~in2));
- endmodule
连续的异或操作,中间加入了一个非门
- module top_module (
- input in1,
- input in2,
- input in3,
- output out
- );
- assign out = (~(in1 ^ in2)) ^ in3;
-
- endmodule
实现各种逻辑门
- 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
实现 7420 芯片的功能,简单的与非门
- 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
对真值表进行逻辑实现,这个答案不唯一。
- module top_module(
- input x3,
- input x2,
- input x1,
- output f
- );
- assign f = x3?x1:x2;
-
- endmodule
- module top_module (
- input [1:0] A,
- input [1:0] B,
- output z
- );
- assign z = (A == B)? 1:0;
-
- endmodule
- module top_module (
- input x,
- input y,
- output z
- );
- assign z = (x ^ y) & x;
-
- endmodule
- module top_module (
- input x,
- input y,
- output z
- );
- assign z = ~(x ^ y);
-
- endmodule
联合前面的电路 A 和 B 的功能,但也可以直接逻辑实现,不必调用之前的模块。
- module top_module (
- input x,
- input y,
- output z
- );
- wire a1,a2,b1,b2;
- wire sum1,sum2;
-
- assign a1 = (x ^ y) & x;
- assign b1 = ~(x ^ y);
- assign a2 = (x ^ y) & x;
- assign b2 = ~(x ^ y);
-
- assign sum1 = a1 | b1;
- assign sum2 = a2 & b2;
-
- assign z = sum1 ^ sum2;
-
- endmodule
设计一个电路来控制手机的振铃器和振动电机。每当电话需要从来电响铃,您的电路必须打开铃声或电机,但不能同时打开两者。如果手机处于振动模式,请打开电机。否则,请打开铃声。
input ring
output ringer = 1
output motor = 1
input vibrate_mode = 1
- module top_module (
- input ring,
- input vibrate_mode,
- output ringer,
- output motor
- );
-
- assign ringer = ((ring == 1'b1) && (vibrate_mode == 1'b0))? 1'b1:1'b0;
- assign motor = ((vibrate_mode ==1'b1) && (ring == 1'b1))? 1'b1:1'b0;
加热/冷却恒温器控制加热器(冬季)和空调(夏季)。实现一个电路,该电路将根据需要打开和关闭加热器,空调和鼓风机风扇。
恒温器可以处于以下两种模式之一:加热和冷却。在加热模式下,当加热器太冷时打开,但不要使用空调。在冷却模式下,当空调太热时打开,但不要打开加热器。当加热器或空调打开时,也要打开风扇以循环空气。此外,用户还可以要求风扇打开,即使加热器和空调关闭。
mode = 1
mode = 0
too_cold = 1
too_hot = 1
fan_on = 1
尝试仅使用语句,以查看是否可以将问题描述转换为逻辑门的集合。
- 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
“总体计数”电路对输入向量中的'1'的数量进行计数。为 3 位输入矢量构建总体计数电路。
逻辑实现嵌套。
- module top_module(
- input [2:0] in,
- output [1:0] out
- );
-
- assign out = (in=='d1 | in=='d2 | in=='d4)?'d1:((in=='d3 | in=='d5 | in=='d6)?'d2:((~in)?'d0:'d3));
-
- endmodule
在 [3:0] 中,将获得一个四位输入向量。我们想知道每个位与其邻位间的一些关系:
- 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[0] = (in[0] & in[1]);
- assign out_both[1] = (in[1] & in[2]);
- assign out_both[2] = (in[2] & in[3]);
- assign out_any[1] = (in[1] | in[0]);
- assign out_any[2] = (in[2] | in[1]);
- assign out_any[3] = (in[3] | in[2]);
- assign out_different[0] = (in[0] != in[1]);
- assign out_different[1] = (in[1] != in[2]);
- assign out_different[2] = (in[2] != in[3]);
- assign out_different[3] = (in[3] != in[0]);
-
- endmodule
和上题类似
- 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[98:0] = in[99:1] & in[98:0];
- assign out_any[99:1] = in[99:1] | in[98:0];
- assign out_different[98:0] = in[98:0] ^ in[99:1];
- assign out_different[99] = in[99] ^ in[0];
-
- endmodule
创建一个 1 位宽的 2 对 1 多路复用器。当 sel=0 时,选择a。当 sel=1 时,选择 b。
- module top_module(
- input a, b, sel,
- output out
- );
- assign out = sel?b:a;
-
- endmodule
创建一个 100 位宽的 2 对 1 多路复用器。当 sel=0 时,选择a。当 sel=1 时,选择 b。
- module top_module(
- input [99:0] a, b,
- input sel,
- output [99:0] out
- );
- assign out = sel?b:a;
-
- endmodule
创建 16 位宽、9 对 1 多路复用器。sel=0 选择 a,sel=1 选择 b,依此类推。对于未使用的情况(sel=9 到 15),请将所有输出位设置为“1”。
- module top_module(
- input [15:0] a, b, c, d, e, f, g, h, i,
- input [3:0] sel,
- output [15:0] out
- );
- assign out = (sel=='d0)?a:((sel=='d1)?b:((sel=='d2)?c:((sel=='d3)?d:((sel=='d4)?e:((sel=='d5)?f:((sel=='d6)?g:((sel=='d7)?h:((sel=='d8)?i:16'hffff))))))));
-
- endmodule
创建 16 位宽、9 对 1 多路复用器。sel=0 选择 a,sel=1 选择 b,依此类推。对于未使用的情况(sel=9 到 15),请将所有输出位设置为“1”。
- module top_module(
- input [255:0] in,
- input [7:0] sel,
- output out
- );
- assign out = in[sel];
-
- endmodule
创建 16 位宽、9 对 1 多路复用器。sel=0 选择 a,sel=1 选择 b,依此类推。对于未使用的情况(sel=9 到 15),请将所有输出位设置为“1”。
- module top_module(
- input [1023:0] in,
- input [7:0] sel,
- output [3:0] out
- );
- assign out = in[sel*4+3-:4];
-
- endmodule
创建一个半加法器。半加法器添加两个位(无残留),并产生总和和并执行。
- module top_module (
- input [7:0] a,
- input [7:0] b,
- output [7:0] s,
- output overflow
- );
-
- assign s = a + b;
- assign overflow = (~a[7] & ~b[7] & s[7]) | (a[7] & b[7] & ~s[7]);
-
- endmodule
创建完整添加器。一个完整的加法器添加三个位,并产生一个总和并执行。
- module top_module(
- input a, b, cin,
- output cout, sum
- );
- assign {cout,sum} = a + b + cin;
- endmodule
创建3个实例以创建3位二进制纹波携带加法器。加法器将两个3位数字和一个随身数字相加,以生成3位求和并执行。从纹波携带加法器中的每个完整加法器输出执行。cout[2] 是最后一个完整加法器的最终执行。
- module top_module(
- input [2:0] a, b,
- input cin,
- output [2:0] cout,
- output [2:0] sum
- );
- assign {cout[0],sum[0]} = a[0] + b[0] + cin;
- assign {cout[1],sum[1]} = a[1] + b[1] + cout[0];
- assign {cout[2],sum[2]} = a[2] + b[2] + cout[1];
-
- endmodule
做行进波累加器,全加器
- module top_module (
- input [3:0] x,
- input [3:0] y,
- output [4:0] sum
- );
-
- wire cin1,cin2,cin3;
-
- assign {cin1,sum[0]} = x[0] + y[0];
- assign {cin2,sum[1]} = x[1] + y[1] + cin1;
- assign {cin3,sum[2]} = x[2] + y[2] + cin2;
- assign {sum[4],sum[3]} = x[3] + y[3] + cin3;
-
- endmodule
假设有两个 8 位 2 的补码数,a[7:0] 和 b[7:0]。这些数字相加产生s[7:0]。还要计算是否发生了(有符号)溢出。两个正数相加符号位变成了1表示溢出,两个负数相加符号位变成了0表示溢出。
- module top_module (
- input [7:0] a,
- input [7:0] b,
- output [7:0] s,
- output overflow
- );
-
- assign s = a + b;
- assign overflow = (~a[7] & ~b[7] & s[7]) | (a[7] & b[7] & ~s[7]);
-
- endmodule
创建 100 位二进制加法器。加法器将两个 100 位数字和进位相加,以产生 100 位总和。
- module top_module(
- input [99:0] a, b,
- input cin,
- output cout,
- output [99:0] sum
- );
- assign {cout,sum} = a+b+cin;
-
- endmodule
实例化 4 个bcd_fadd模块以创建 4 位 BCD 纹波携带加法器。加法器应添加两个 4 位 BCD 数字(打包成 16 位向量)和进位值,以生成 4 位总和并执行。
- module top_module (
- input [15:0] a, b,
- input cin,
- output cout,
- output [15:0] sum
- );
-
- wire cin1,cin2,cin3;
-
- bcd_fadd bcd_fadd_inst1(
- .a (a[3:0]),
- .b (b[3:0]),
- .cin (cin),
- .cout (cin1),
- .sum (sum[3:0])
- );
-
- bcd_fadd bcd_fadd_inst2(
- .a (a[7:4]),
- .b (b[7:4]),
- .cin (cin1),
- .cout (cin2),
- .sum (sum[7:4])
- );
-
- bcd_fadd bcd_fadd_inst3(
- .a (a[11:8]),
- .b (b[11:8]),
- .cin (cin2),
- .cout (cin3),
- .sum (sum[11:8])
- );
-
- bcd_fadd bcd_fadd_inst4(
- .a (a[15:12]),
- .b (b[15:12]),
- .cin (cin3),
- .cout (cout),
- .sum (sum[15:12])
- );
-
- endmodule
根据卡诺图得出逻辑实现
- module top_module(
- input a,
- input b,
- input c,
- output out
- );
- assign out = ((~a)&(~b)&(~c))?'d0:'d1;
-
- endmodule
根据卡诺图得出逻辑实现
- module top_module(
- input a,
- input b,
- input c,
- input d,
- output out
- );
-
- assign out = (a&~b&c&d)|(~a&b&~c&~d)|(~a&c&~d)|(b&c&d)|(~b&~c);
-
- endmodule
根据卡诺图得出逻辑实现
- module top_module(
- input a,
- input b,
- input c,
- input d,
- output out
- );
-
- assign out = (a&~c&~d)|(~b&c)|(a&b&c);
- endmodule
根据卡诺图得出逻辑实现
- module top_module(
- input a,
- input b,
- input c,
- input d,
- output out
- );
-
- assign out = (~a&b&~c&~d)|(a&~b&~c&~d)|(~a&~b&~c&d)|(a&b&~c&d)|(~a&b&c&d)|(a&~b&c&d)|(~a&~b&c&~d)|(a&b&c&~d);
- endmodule
具有四个输入(a,b,c,d)的单输出数字系统在输入端出现2、7或15时生成逻辑-1,当0、1、4、5、6、9、10、13或14出现时,生成逻辑-0。数字 3、8、11 和 12 的输入条件在此系统中永远不会出现。例如,7 对应于分别设置为 0,1,1,1 的 a,b,c,d。确定最小 SOP 形式的输出out_sop,以及最小 POS 格式的输出out_pos。
SOP: sum of product
在卡诺图中标定1的为正,0为反,先乘最后相加
POS: product of sum
在卡诺图中标定1的为反,0为正,先加最后相乘再取反
- module top_module (
- input a,
- input b,
- input c,
- input d,
- output out_sop,
- output out_pos
- );
- assign out_sop = (~a&~b*c) | (c&d);
- assign out_pos = ~((a|b|~c) & (~c|~d));
-
- endmodule
根据卡诺图得出逻辑实现
- module top_module (
- input [4:1] x,
- output f
- );
- assign f = (~x[1]&x[3]) | (x[1]&x[2]&~x[3]);
-
- endmodule
根据卡诺图得出逻辑实现
- module top_module (
- input [4:1] x,
- output f
- );
- assign f = (~x[1]&x[3]) | (x[1]&~x[2]&~x[4]) | (x[1]&x[2]&x[3]&x[4]) | (~x[1]&~x[2]&~x[3]&~x[4]);
-
- endmodule
对于下面的Karnaugh图,使用一个4对1多路复用器和尽可能多的2对1多路复用器来提供电路实现,但使用尽可能少。您不得使用任何其他逻辑门,必须使用 a 和 b 作为多路复用器选择器输入,如下面的 4 对 1 多路复用器所示。
- module top_module (
- input c,
- input d,
- output [3:0] mux_in
- );
- assign mux_in[0] = c | d;
- assign mux_in[1] = 'd0;
- assign mux_in[2] = ~d;
- assign mux_in[3] = c & d;
- endmodule