当前位置: 首页 > news >正文

【HDLBits】Circuits—Combinational Logic合集(包含答案推导过程)

文章目录

  • 1. Basic Gates
    • 1.1 Wire
    • 1.2 AND
    • 1.3 NOR
    • 1.4 Another gate
    • 1.5 Two gates
    • 1.6 More logic gates
    • 1.7 7420 chip
    • 1.8 Truth table
    • Synthesizing a circuit from a truth table 根据真值表推逻辑式
    • 练习:Truthtable1
    • 1.9 Two-bit equility
    • 1.10 Simple circuit A
    • 1.11 Simple circuit B
    • 1.12 Combine circuit A and B
    • 1.13 ring and vibrate?
    • 1.14 Thermostat
    • 1.15 3-bit population count
    • 1.16 Gates and Vectors
    • 1.17 Even longer vector
  • 2. Multiplexers
    • 2.1 2-to-1 multiplexer
    • 2.2 2-to-1 bus multiplexer
    • 2.3 9-to-1 multiplexer
    • 2.4 256-to-1 multiplexer
    • 2.5 256-to-1 4-bit multiplexer
  • 3. Arithmetic Circuits
    • 3.1 Half adder
    • 3.2 Full adder
    • 3.3 3-bit binary adder
    • 3.4 Adder
    • 3.5 signed addition overflow
    • 3.6 100-bit binary adder
    • 3.7 4-digit BCD adder
  • 4. Karnaugh map to Circuit
    • 4.1 3-variable
    • 4.2 4-variable
    • 4.3 4-variable
    • 4.4 4-variable
    • 4.5 Minimum SOP and POS
    • 4.6 Karnaugh map
    • 4.7 Karnaugh map
    • 4.8 K-map implemented with a multiplexer

1. Basic Gates

1.1 Wire

Implement the following circuit:
在这里插入图片描述

module top_module (
    input in,
    output out);
    
    assign out = in;

endmodule

1.2 AND

Implement the following circuit:
在这里插入图片描述

module top_module (
    output out);
    
    assign out = 1'b0;

endmodule

1.3 NOR

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    output out);
    
    assign out = ~(in1|in2);

endmodule

1.4 Another gate

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    output out);
    
    assign out = in1&(~in2);

endmodule

1.5 Two gates

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    input in3,
    output out);
    
    assign out = ~(in1^in2)^in3;

endmodule

1.6 More logic gates

Ok, let’s try building several logic gates at the same time. Build a combinational circuit with two inputs, a and b.
There are 7 outputs, each with a logic gate driving it:
out_and: a and b
out_or: a or b
out_xor: a xor b
out_nand: a nand b
out_nor: a nor b
out_xnor: a xnor b
out_anotb: a and-not b

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

1.7 7420 chip

The 7400-series integrated circuits are a series of digital chips with a few gates each. The 7420 is a chip with two 4-input NAND gates.

Create a module with the same functionality as the 7420 chip. It has 8 inputs and 2 outputs.
在这里插入图片描述

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

1.8 Truth table

In the previous exercises, we used simple logic gates and combinations of several logic gates. These circuits are examples of combinational circuits. Combinational means the outputs of the circuit is a function (in the mathematics sense) of only its inputs. This means that for any given input value, there is only one possible output value. Thus, one way to describe the behaviour of a combinational function is to explicitly list what the output should be for every possible value of the inputs. This is a truth table.
For a boolean function of N inputs, there are 2N possible input combinations. Each row of the truth table lists one input combination, so there are always 2N rows. The output column shows what the output should be for each input value.
在这里插入图片描述
The above truth table is for a three-input, one-output function. It has 8 rows for each of the 8 possible input combinations, and one output column. There are four inputs combinations where the output is 1, and four where the output is 0.

Synthesizing a circuit from a truth table 根据真值表推逻辑式

第一步:从真值表内找输出端为“1”的各行,把每行的输入变量写成**乘积(&)**形式;遇到“0”的输入变量上加非号。
第二步:把各乘积项相加( | )

练习:Truthtable1

在这里插入图片描述

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

1.9 Two-bit equility

Create a circuit that has two 2-bit inputs A[1:0] and B[1:0], and produces an output z. The value of z should be 1 if A = B, otherwise z should be 0.

module top_module ( input [1:0] A, input [1:0] B, output z ); 
    always @(*)begin
        if(A[1:0]==B[1:0])
            z=1;
        else
            z=0;
    end

	//另一个方法
	//assign = (A[1:0]==B[1:0]);
	
endmodule

1.10 Simple circuit A

Module A is supposed to implement the function z = (x^y) & x. Implement this module.

module top_module (input x, input y, output z);
    
    assign z=(x^y) & x;

endmodule

1.11 Simple circuit B

Circuit B can be described by the following simulation waveform:
在这里插入图片描述

module top_module ( input x, input y, output z );
    
    assign z = ((~x)&(~y)) | (x&y);

	// Or: Notice this is an XNOR.
	assign z = ~(x^y);

endmodule

1.12 Combine circuit A and B

在这里插入图片描述

module top_module (input x, input y, output z);
    wire z1,z2,z3,z4;
    
    a a1(x,y,z1);
    b b1(x,y,z2);
    a a2(x,y,z3);
    b b2(x,y,z4);
    
    assign z= (z1|z2)^(z3&z4);
    
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

1.13 ring and vibrate?

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.
在这里插入图片描述

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);
    // When should ringer be on? When (phone is ringing) and (phone is not in vibrate mode)
    assign ringer = ring&(~vibrate_mode);
    
    // When should motor be on? When (phone is ringing) and (phone is in vibrate mode)
    assign motor = ring&vibrate_mode;

endmodule

1.14 Thermostat

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
);
	// Reminder: The order in which you write assign statements doesn't matter. 
	// assign statements describe circuits, so you get the same circuit in the end
	// regardless of which portion you describe first.

	// Fan should be on when either heater or aircon is on, and also when requested to do so (fan_on = 1).
	assign fan = heater | aircon | fan_on;
	
	// Heater is on when it's too cold and mode is "heating".
	assign heater = (mode & too_cold);
	
	// Aircon is on when it's too hot and mode is not "heating".
	assign aircon = (~mode & too_hot);
	
	// * Unlike real thermostats, there is no "off" mode here.
	
endmodule

1.15 3-bit population count

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
        out = 2'd0;
        for(int i=0;i<3;i++)
           if(in[i]==1'b1)
                out = out+2'd1;
            else
                out = out;
    end

endmodule

1.16 Gates and Vectors

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].
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]};
	
endmodule

1.17 Even longer vector

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].

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[99:1]&in[98:0];
    assign out_any = in[98:0]|in[99:1];
    assign out_different = in ^ {in[0],in[99:1]};

endmodule

2. Multiplexers

2.1 2-to-1 multiplexer

Create a one-bit wide, 2-to-1 multiplexer. When sel=0, choose a. When sel=1, choose b.

module top_module( 
    input a, b, sel,
    output out ); 
    
    assign out = sel ? b : a;

endmodule

2.2 2-to-1 bus multiplexer

Create a 100-bit wide, 2-to-1 multiplexer. When sel=0, choose a. When sel=1, choose b.

module top_module( 
    input [99:0] a, b,
    input sel,
    output [99:0] out );
    
    assign out = sel?b:a;

endmodule

2.3 9-to-1 multiplexer

Create a 16-bit wide, 9-to-1 multiplexer. sel=0 chooses a, sel=1 chooses b, etc. For the unused cases (sel=9 to 15), set all output bits to ‘1’.

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );
    
    always @(*)begin
        case(sel)
        	4'h0: out = a;
            4'h1: out = b;
            4'h2: out = c;
            4'h3: out = d;
            4'h4: out = e;
            4'h5: out = f;
            4'h6: out = g;
            4'h7: out = h;
            4'h8: out = i;
            default: out = {16{1'b1}};    
        endcase
    end
    
endmodule

2.4 256-to-1 multiplexer

Create a 1-bit wide, 256-to-1 multiplexer. The 256 inputs are all packed into a single 256-bit input vector. sel=0 should select in[0], sel=1 selects bits in[1], sel=2 selects bits in[2], etc.

module top_module( 
    input [255:0] in,
    input [7:0] sel,
    output out );
    
    assign out = in[sel];

endmodule

2.5 256-to-1 4-bit multiplexer

Create a 4-bit wide, 256-to-1 multiplexer. The 256 4-bit inputs are all packed into a single 1024-bit input vector. sel=0 should select bits in[3:0], sel=1 selects bits in[7:4], sel=2 selects bits in[11:8], etc.

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    
    // 错误写法: assign out = in[4*sel+3:4*sel]; 
    //verilog中要求向量下标可以是变量,但是位宽必须是常量
    
    assign out = {in[4*sel+3],in[4*sel+2],in[4*sel+1],in[4*sel]};
   
endmodule

3. Arithmetic Circuits

3.1 Half adder

Create a half adder. A half adder adds two bits (with no carry-in) and produces a sum and carry-out.
在这里插入图片描述

module top_module( 
    input a, b,
    output cout, sum );
    
    assign sum = a^b;
    assign cout = a&b;

endmodule

3.2 Full adder

Create a full adder. A full adder adds three bits (including carry-in) and produces a sum and carry-out.
在这里插入图片描述
在这里插入图片描述

module top_module( 
    input a, b, cin,
    output cout, sum );
    
    assign sum = a^b^cin;
    assign cout = a&b | a&cin | b&cin;

endmodule

3.3 3-bit binary adder

Now that you know how to build a full adder, make 3 instances of it to create a 3-bit binary ripple-carry adder. The adder adds two 3-bit numbers and a carry-in to produce a 3-bit sum and carry out.
To encourage you to actually instantiate full adders, also output the carry-out from each full adder in the ripple-carry adder. cout[2] is the final carry-out from the last full adder, and is the carry-out you usually see.

module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum );
    
    add add1(a[0],b[0],cin,cout[0],sum[0]);
    add add2(a[1],b[1],cout[0],cout[1],sum[1]);
    add add3(a[2],b[2],cout[1],cout[2],sum[2]);
    
endmodule
module add(input a, input b,input cin, output cout, output sum);
    
    assign sum = a^b^cin;
    assign cout = a&cin | b&cin | a&b;
    
endmodule

3.4 Adder

在这里插入图片描述

module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    
    wire cout0,cout1,cout2;
    FA U1(x[0],y[0],0,cout0,sum[0]);
    FA U2(x[1],y[1],cout0,cout1,sum[1]);
    FA U3(x[2],y[2],cout1,cout2,sum[2]);
    FA U4(x[3],y[3],cout2,sum[4],sum[3]);

	// This circuit is a 4-bit ripple-carry adder with carry-out.
	//assign sum = x+y;	// Verilog addition automatically produces the carry-out bit.

	// Verilog quirk: Even though the value of (x+y) includes the carry-out, (x+y) is still considered to be a 4-bit number (The max width of the two operands).
	// This is correct:
	// assign sum = (x+y);
	// But this is incorrect:
	// assign sum = {x+y};	// Concatenation operator: This discards the carry-out
    
endmodule

module FA ( input a, input b, input cin, output cout,output sum);
	assign sum = a^b^cin;
    assign cout = a&b|a&cin|b&cin;
endmodule

3.5 signed addition overflow

Assume that you have two 8-bit 2’s complement numbers, a[7:0] and b[7:0]. These numbers are added to produce s[7:0]. Also compute whether a (signed) overflow has occurred.
实现8位有符号数据的二进制补码加法,并通过检测符号位变化来判断是否发生溢出

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

3.6 100-bit binary adder

Create a 100-bit binary adder. The adder adds two 100-bit numbers and a carry-in to produce a 100-bit sum and carry out.

module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    
    assign {cout,sum} = a+b+cin;

endmodule

3.7 4-digit BCD adder

You are provided with a BCD (binary-coded decimal) one-digit adder named bcd_fadd that adds two BCD digits and carry-in, and produces a sum and carry-out.

module bcd_fadd (
    input [3:0] a,
    input [3:0] b,
    input     cin,
    output   cout,
    output [3:0] sum );

Instantiate 4 copies of bcd_fadd to create a 4-digit BCD ripple-carry adder. Your adder should add two 4-digit BCD numbers (packed into 16-bit vectors) and a carry-in to produce a 4-digit sum and carry out.

module top_module ( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
    
    wire cout1,cout2,cout3;
    
    bcd_fadd u1(
        a[3:0] ,
        b[3:0] ,
        cin   ,
        cout1   ,
        sum[3:0]  );
    
    bcd_fadd u2(
        a[7:4] ,
        b[7:4] ,
        cout1   ,
        cout2   ,
        sum[7:4] );
    
    bcd_fadd u3(
        a[11:8] ,
        b[11:8] ,
        cout2   ,
        cout3   ,
        sum[11:8]  );
    
    bcd_fadd u4(
        a[15:12],
        b[15:12] ,
        cout3,
        cout,
        sum[15:12]  );
    

endmodule

4. Karnaugh map to Circuit

卡诺图的相关知识可以去这里看:https://zhuanlan.zhihu.com/p/158535749

4.1 3-variable

在这里插入图片描述
out = a + b + c

module top_module(
    input a,
    input b,
    input c,
    output out  ); 
    
    assign out = a | b | c ;

endmodule

4.2 4-variable

在这里插入图片描述

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = (~b & ~c) | (~a & ~d) | (b & c & d) | (a & ~b & d) ; 

endmodule

4.3 4-variable

与上题不同的是,该卡诺图中出现d,其值可以有自己随意设定来方便化简。
在这里插入图片描述

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = a | (~b & c) ; 

endmodule

4.4 4-variable

在这里插入图片描述

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = a ^ b ^ c ^ d;

endmodule

4.5 Minimum SOP and POS

A single-output digital system with four inputs (a,b,c,d) generates a logic-1 when 2, 7, or 15 appears on the inputs, and a logic-0 when 0, 1, 4, 5, 6, 9, 10, 13, or 14 appears. The input conditions for the numbers 3, 8, 11, and 12 never occur in this system. For example, 7 corresponds to a,b,c,d being set to 0,1,1,1, respectively.
Determine the output out_sop in minimum SOP form, and the output out_pos in minimum POS form.
在这里插入图片描述

module top_module (
    input a,
    input b,
    input c,
    input d,
    output out_sop,
    output out_pos
); 
    assign out_sop = (c & d) | (~a & ~b & c);
    assign out_pos = c & (~a|d) & (~b|d);

endmodule

4.6 Karnaugh map

在这里插入图片描述

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

endmodule

4.7 Karnaugh map

在这里插入图片描述

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

endmodule

4.8 K-map implemented with a multiplexer

For the following Karnaugh map, give the circuit implementation using one 4-to-1 multiplexer and as many 2-to-1 multiplexers as required, but using as few as possible. You are not allowed to use any other logic gate and you must use a and b as the multiplexer selector inputs, as shown on the 4-to-1 multiplexer below.

You are implementing just the portion labelled top_module, such that the entire circuit (including the 4-to-1 mux) implements the K-map.
在这里插入图片描述

在这里插入图片描述
(The requirement to use only 2-to-1 multiplexers exists because the original exam question also wanted to test logic function simplification using K-maps and how to synthesize logic functions using only multiplexers. If you wish to treat this as purely a Verilog exercise, you may ignore this constraint and write the module any way you wish.)

module top_module (
    input c,
    input d,
    output [3:0] mux_in
); 
    assign mux_in[0] = c | d;
    assign mux_in[1] = 0;
    assign mux_in[2] = ~d;
    assign mux_in[3] = c & d;
    
endmodule

相关文章:

  • 有序数组双指针问题
  • Flutter TextFormField 完全手册与设计最佳实践
  • MyBatis 中 #{} 和 ${} 的区别详解
  • 前沿分享|处理LLM幻觉问题-CoN|笔记链:增强检索增强语言模型的鲁棒性
  • 数据中台建设系列(一):数据中台的前世今生
  • Spring AI Alibaba ChatModel使用
  • debian12 安装docker服务
  • Java 方法执行原理底层解析
  • spss statistics 在mac上安装
  • 【leetcode hot 100 131】分割回文串
  • Docker 安装 Mysql
  • Ubuntu 20.04 安装并使用Cursor
  • go语言中的strings库
  • 蓝桥杯 R格式
  • Redis常见阻塞原因总结
  • 【JavaEE进阶】Linux搭建Java部署环境
  • 用Ollama部署大语言模型
  • ABAP隐藏F8执行按钮
  • Kafka是如何实现幂等性的??
  • redis安装
  • 岭南非遗大IP来上海了,舞剧《英歌》在文化广场连演两场
  • 毕节两兄弟摘马蜂窝致路人被蜇去世,涉嫌过失致人死亡罪被公诉
  • 商务部召开外资企业圆桌会
  • 上海4-6月文博美展、剧目演出不断,将开设直播推出文旅优惠套餐
  • 厦门国贸去年营收约3544亿元,净利润同比减少67.3%
  • 商务部:一季度社零总额12.47万亿元,同比增长4.6%