• 【HDLBits 刷题】Circuits(1)Combinational Logic


    目录

    写在前面

    Combinational Logic

    Basic Gates

    Wire

    GND

    NOR

    Another gate

    Two gates

    More logic gates

    7420 chips

    Truth table

    Two bit equality

    Simple circuit A

    Simple circuit B

    Combine circuits A and B

    Ring or vibrate

    Thermostat

    3 bit population count

    Gates and vectors

    Even longer vectors

    Multiplexers

    2 to 1 mux

    2 to 1 bus mux

    9 to 1 mux

    256 to 1 mux

    256 to 1 4bit mux

    Arithmetic Circuits

    half addr

    full addr

    3 bit bin addr

    addr

    signed add over

    100 bit bin addr

    4 digit BCD addr

    Karnaugh Map to Circuit

    kamp1

    kamp2

    kamp3

    kamp4

    min_SOP

    kmap5

    kmap6

    kmap imple


    写在前面

    本篇博客对 Circuits 部分的组合逻辑前两节做答案和部分解析,一些比较简单的题目就直接给出答案,有些难度再稍作讲解,每道题的答案不一定唯一,可以有多种解决方案,欢迎共同讨论。

    Combinational Logic

    Basic Gates

    Wire

    简单的逻辑实现

    1. module top_module (
    2. input in,
    3. output out
    4. );
    5. assign out = in;
    6. endmodule

    GND

    对输出直接接地,言外之意就是将输出置0

    1. module top_module (
    2. output out
    3. );
    4. assign out = 1'b0;
    5. endmodule

    NOR

    实现或非门

    1. module top_module (
    2. input in1,
    3. input in2,
    4. output out
    5. );
    6. assign out = !(in1 | in2);
    7. endmodule

    Another gate

    1. module top_module (
    2. input in1,
    3. input in2,
    4. output out
    5. );
    6. assign out = (in1 & (~in2));
    7. endmodule

    Two gates

    连续的异或操作,中间加入了一个非门

    1. module top_module (
    2. input in1,
    3. input in2,
    4. input in3,
    5. output out
    6. );
    7. assign out = (~(in1 ^ in2)) ^ in3;
    8. endmodule

    More logic gates

    实现各种逻辑门

    1. module top_module(
    2. input a, b,
    3. output out_and,
    4. output out_or,
    5. output out_xor,
    6. output out_nand,
    7. output out_nor,
    8. output out_xnor,
    9. output out_anotb
    10. );
    11. assign out_and = a & b;
    12. assign out_or = a | b;
    13. assign out_xor = a ^ b;
    14. assign out_nand = ~(a & b);
    15. assign out_nor = ~(a | b);
    16. assign out_xnor = ~(a ^ b);
    17. assign out_anotb = a & (~b);
    18. endmodule

    7420 chips

    实现 7420 芯片的功能,简单的与非门

    1. module top_module (
    2. input p1a, p1b, p1c, p1d,
    3. output p1y,
    4. input p2a, p2b, p2c, p2d,
    5. output p2y
    6. );
    7. assign p1y = ~(p1a & p1b & p1c & p1d);
    8. assign p2y = ~(p2a & p2b & p2c & p2d);
    9. endmodule

    Truth table

    对真值表进行逻辑实现,这个答案不唯一。

    1. module top_module(
    2. input x3,
    3. input x2,
    4. input x1,
    5. output f
    6. );
    7. assign f = x3?x1:x2;
    8. endmodule

    Two bit equality

    1. module top_module (
    2. input [1:0] A,
    3. input [1:0] B,
    4. output z
    5. );
    6. assign z = (A == B)? 1:0;
    7. endmodule

    Simple circuit A

    1. module top_module (
    2. input x,
    3. input y,
    4. output z
    5. );
    6. assign z = (x ^ y) & x;
    7. endmodule

    Simple circuit B

    1. module top_module (
    2. input x,
    3. input y,
    4. output z
    5. );
    6. assign z = ~(x ^ y);
    7. endmodule

    Combine circuits A and B

    联合前面的电路 A 和 B 的功能,但也可以直接逻辑实现,不必调用之前的模块。

    1. module top_module (
    2. input x,
    3. input y,
    4. output z
    5. );
    6. wire a1,a2,b1,b2;
    7. wire sum1,sum2;
    8. assign a1 = (x ^ y) & x;
    9. assign b1 = ~(x ^ y);
    10. assign a2 = (x ^ y) & x;
    11. assign b2 = ~(x ^ y);
    12. assign sum1 = a1 | b1;
    13. assign sum2 = a2 & b2;
    14. assign z = sum1 ^ sum2;
    15. endmodule

    Ring or vibrate

    设计一个电路来控制手机的振铃器和振动电机。每当电话需要从来电响铃,您的电路必须打开铃声或电机,但不能同时打开两者。如果手机处于振动模式,请打开电机。否则,请打开铃声。

    input ring 

    output ringer = 1

    output motor = 1

    input vibrate_mode = 1

    1. module top_module (
    2. input ring,
    3. input vibrate_mode,
    4. output ringer,
    5. output motor
    6. );
    7. assign ringer = ((ring == 1'b1) && (vibrate_mode == 1'b0))? 1'b1:1'b0;
    8. assign motor = ((vibrate_mode ==1'b1) && (ring == 1'b1))? 1'b1:1'b0;

    Thermostat

    加热/冷却恒温器控制加热器(冬季)和空调(夏季)。实现一个电路,该电路将根据需要打开和关闭加热器,空调和鼓风机风扇。

    恒温器可以处于以下两种模式之一:加热和冷却。在加热模式下,当加热器太冷时打开,但不要使用空调。在冷却模式下,当空调太热时打开,但不要打开加热器。当加热器或空调打开时,也要打开风扇以循环空气。此外,用户还可以要求风扇打开,即使加热器和空调关闭。

    mode = 1 mode = 0 too_cold = 1 too_hot = 1 fan_on = 1

    尝试仅使用语句,以查看是否可以将问题描述转换为逻辑门的集合。

    1. module top_module (
    2. input too_cold,
    3. input too_hot,
    4. input mode,
    5. input fan_on,
    6. output heater,
    7. output aircon,
    8. output fan
    9. );
    10. assign heater = too_cold & mode;
    11. assign aircon = too_hot & ~mode;
    12. assign fan = fan_on | heater | aircon;
    13. endmodule

    3 bit population count

    “总体计数”电路对输入向量中的'1'的数量进行计数。为 3 位输入矢量构建总体计数电路。

    逻辑实现嵌套。

    1. module top_module(
    2. input [2:0] in,
    3. output [1:0] out
    4. );
    5. assign out = (in=='d1 | in=='d2 | in=='d4)?'d1:((in=='d3 | in=='d5 | in=='d6)?'d2:((~in)?'d0:'d3));
    6. endmodule

    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]应指示[2]或[1]中是否为1。由于 in[0] 没有右边数,所以我们不需要知道out_any[0]。
    • out_different:此输出向量的每个位都应指示相应的输入位是否与其左侧不同。例如,out_different[2]应指示 in[2] 是否与 in[3] 不同。对于这部分,将向量视为环绕,因此在[3]中左邻位在[0]中。
    1. module top_module(
    2. input [3:0] in,
    3. output [2:0] out_both,
    4. output [3:1] out_any,
    5. output [3:0] out_different
    6. );
    7. assign out_both[0] = (in[0] & in[1]);
    8. assign out_both[1] = (in[1] & in[2]);
    9. assign out_both[2] = (in[2] & in[3]);
    10. assign out_any[1] = (in[1] | in[0]);
    11. assign out_any[2] = (in[2] | in[1]);
    12. assign out_any[3] = (in[3] | in[2]);
    13. assign out_different[0] = (in[0] != in[1]);
    14. assign out_different[1] = (in[1] != in[2]);
    15. assign out_different[2] = (in[2] != in[3]);
    16. assign out_different[3] = (in[3] != in[0]);
    17. endmodule

    Even longer vectors

    和上题类似

    1. module top_module(
    2. input [99:0] in,
    3. output [98:0] out_both,
    4. output [99:1] out_any,
    5. output [99:0] out_different
    6. );
    7. assign out_both[98:0] = in[99:1] & in[98:0];
    8. assign out_any[99:1] = in[99:1] | in[98:0];
    9. assign out_different[98:0] = in[98:0] ^ in[99:1];
    10. assign out_different[99] = in[99] ^ in[0];
    11. endmodule

    Multiplexers

    2 to 1 mux

    创建一个 1 位宽的 2 对 1 多路复用器。当 sel=0 时,选择a。当 sel=1 时,选择 b。

    1. module top_module(
    2. input a, b, sel,
    3. output out
    4. );
    5. assign out = sel?b:a;
    6. endmodule

    2 to 1 bus mux

    创建一个 100 位宽的 2 对 1 多路复用器。当 sel=0 时,选择a。当 sel=1 时,选择 b。

    1. module top_module(
    2. input [99:0] a, b,
    3. input sel,
    4. output [99:0] out
    5. );
    6. assign out = sel?b:a;
    7. endmodule

    9 to 1 mux

    创建 16 位宽、9 对 1 多路复用器。sel=0 选择 a,sel=1 选择 b,依此类推。对于未使用的情况(sel=9 到 15),请将所有输出位设置为“1”。

    1. module top_module(
    2. input [15:0] a, b, c, d, e, f, g, h, i,
    3. input [3:0] sel,
    4. output [15:0] out
    5. );
    6. 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))))))));
    7. endmodule

    256 to 1 mux

    创建 16 位宽、9 对 1 多路复用器。sel=0 选择 a,sel=1 选择 b,依此类推。对于未使用的情况(sel=9 到 15),请将所有输出位设置为“1”。

    1. module top_module(
    2. input [255:0] in,
    3. input [7:0] sel,
    4. output out
    5. );
    6. assign out = in[sel];
    7. endmodule

    256 to 1 4bit mux

    创建 16 位宽、9 对 1 多路复用器。sel=0 选择 a,sel=1 选择 b,依此类推。对于未使用的情况(sel=9 到 15),请将所有输出位设置为“1”。

    1. module top_module(
    2. input [1023:0] in,
    3. input [7:0] sel,
    4. output [3:0] out
    5. );
    6. assign out = in[sel*4+3-:4];
    7. endmodule

    Arithmetic Circuits

    half addr

    创建一个半加法器。半加法器添加两个位(无残留),并产生总和和并执行。

    1. module top_module (
    2. input [7:0] a,
    3. input [7:0] b,
    4. output [7:0] s,
    5. output overflow
    6. );
    7. assign s = a + b;
    8. assign overflow = (~a[7] & ~b[7] & s[7]) | (a[7] & b[7] & ~s[7]);
    9. endmodule

    full addr

    创建完整添加器。一个完整的加法器添加三个位,并产生一个总和并执行。

    1. module top_module(
    2. input a, b, cin,
    3. output cout, sum
    4. );
    5. assign {cout,sum} = a + b + cin;
    6. endmodule

    3 bit bin addr

    创建3个实例以创建3位二进制纹波携带加法器。加法器将两个3位数字和一个随身数字相加,以生成3位求和并执行。从纹波携带加法器中的每个完整加法器输出执行。cout[2] 是最后一个完整加法器的最终执行。

    1. module top_module(
    2. input [2:0] a, b,
    3. input cin,
    4. output [2:0] cout,
    5. output [2:0] sum
    6. );
    7. assign {cout[0],sum[0]} = a[0] + b[0] + cin;
    8. assign {cout[1],sum[1]} = a[1] + b[1] + cout[0];
    9. assign {cout[2],sum[2]} = a[2] + b[2] + cout[1];
    10. endmodule

    addr

    做行进波累加器,全加器

    1. module top_module (
    2. input [3:0] x,
    3. input [3:0] y,
    4. output [4:0] sum
    5. );
    6. wire cin1,cin2,cin3;
    7. assign {cin1,sum[0]} = x[0] + y[0];
    8. assign {cin2,sum[1]} = x[1] + y[1] + cin1;
    9. assign {cin3,sum[2]} = x[2] + y[2] + cin2;
    10. assign {sum[4],sum[3]} = x[3] + y[3] + cin3;
    11. endmodule

    signed add over

    假设有两个 8 位 2 的补码数,a[7:0] 和 b[7:0]。这些数字相加产生s[7:0]。还要计算是否发生了(有符号)溢出。两个正数相加符号位变成了1表示溢出,两个负数相加符号位变成了0表示溢出。

    1. module top_module (
    2. input [7:0] a,
    3. input [7:0] b,
    4. output [7:0] s,
    5. output overflow
    6. );
    7. assign s = a + b;
    8. assign overflow = (~a[7] & ~b[7] & s[7]) | (a[7] & b[7] & ~s[7]);
    9. endmodule

    100 bit bin addr

    创建 100 位二进制加法器。加法器将两个 100 位数字和进位相加,以产生 100 位总和。

    1. module top_module(
    2. input [99:0] a, b,
    3. input cin,
    4. output cout,
    5. output [99:0] sum
    6. );
    7. assign {cout,sum} = a+b+cin;
    8. endmodule

    4 digit BCD addr

    实例化 4 个bcd_fadd模块以创建 4 位 BCD 纹波携带加法器。加法器应添加两个 4 位 BCD 数字(打包成 16 位向量)和进位值,以生成 4 位总和并执行。

    1. module top_module (
    2. input [15:0] a, b,
    3. input cin,
    4. output cout,
    5. output [15:0] sum
    6. );
    7. wire cin1,cin2,cin3;
    8. bcd_fadd bcd_fadd_inst1(
    9. .a (a[3:0]),
    10. .b (b[3:0]),
    11. .cin (cin),
    12. .cout (cin1),
    13. .sum (sum[3:0])
    14. );
    15. bcd_fadd bcd_fadd_inst2(
    16. .a (a[7:4]),
    17. .b (b[7:4]),
    18. .cin (cin1),
    19. .cout (cin2),
    20. .sum (sum[7:4])
    21. );
    22. bcd_fadd bcd_fadd_inst3(
    23. .a (a[11:8]),
    24. .b (b[11:8]),
    25. .cin (cin2),
    26. .cout (cin3),
    27. .sum (sum[11:8])
    28. );
    29. bcd_fadd bcd_fadd_inst4(
    30. .a (a[15:12]),
    31. .b (b[15:12]),
    32. .cin (cin3),
    33. .cout (cout),
    34. .sum (sum[15:12])
    35. );
    36. endmodule

    Karnaugh Map to Circuit

    kamp1

    根据卡诺图得出逻辑实现

    1. module top_module(
    2. input a,
    3. input b,
    4. input c,
    5. output out
    6. );
    7. assign out = ((~a)&(~b)&(~c))?'d0:'d1;
    8. endmodule

    kamp2

    根据卡诺图得出逻辑实现

    1. module top_module(
    2. input a,
    3. input b,
    4. input c,
    5. input d,
    6. output out
    7. );
    8. assign out = (a&~b&c&d)|(~a&b&~c&~d)|(~a&c&~d)|(b&c&d)|(~b&~c);
    9. endmodule

    kamp3

    根据卡诺图得出逻辑实现

    1. module top_module(
    2. input a,
    3. input b,
    4. input c,
    5. input d,
    6. output out
    7. );
    8. assign out = (a&~c&~d)|(~b&c)|(a&b&c);
    9. endmodule

    kamp4

    根据卡诺图得出逻辑实现

    1. module top_module(
    2. input a,
    3. input b,
    4. input c,
    5. input d,
    6. output out
    7. );
    8. 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);
    9. endmodule

    min_SOP

    具有四个输入(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为正,先加最后相乘再取反

    1. module top_module (
    2. input a,
    3. input b,
    4. input c,
    5. input d,
    6. output out_sop,
    7. output out_pos
    8. );
    9. assign out_sop = (~a&~b*c) | (c&d);
    10. assign out_pos = ~((a|b|~c) & (~c|~d));
    11. endmodule

    kmap5

    根据卡诺图得出逻辑实现

    1. module top_module (
    2. input [4:1] x,
    3. output f
    4. );
    5. assign f = (~x[1]&x[3]) | (x[1]&x[2]&~x[3]);
    6. endmodule

    kmap6

    根据卡诺图得出逻辑实现

    1. module top_module (
    2. input [4:1] x,
    3. output f
    4. );
    5. 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]);
    6. endmodule

    kmap imple

    对于下面的Karnaugh图,使用一个4对1多路复用器和尽可能多的2对1多路复用器来提供电路实现,但使用尽可能少。您不得使用任何其他逻辑门,必须使用 a 和 b 作为多路复用器选择器输入,如下面的 4 对 1 多路复用器所示。

     

    1. module top_module (
    2. input c,
    3. input d,
    4. output [3:0] mux_in
    5. );
    6. assign mux_in[0] = c | d;
    7. assign mux_in[1] = 'd0;
    8. assign mux_in[2] = ~d;
    9. assign mux_in[3] = c & d;
    10. endmodule
  • 相关阅读:
    zynq开发中的设备树
    外汇天眼:外汇储备减少对新兴市场货币构成风险
    力扣-1832.判断句子是否全为字母句
    python Gui编程工具详解:beeware
    HTML5
    最短路径(Dijkstra算法与Floyd算法)
    Kafka高性能
    计算机网络——如何构造HTTP请求
    嵌入式开发--CubeMX使用入门教程
    Import Error: from torchtext.data import to_map_style_dataset解决方案
  • 原文地址:https://blog.csdn.net/m0_61298445/article/details/126078471