【自用向 刷题笔记/答案】HDLBITS: Circuits - Combinational Logic

该文详细介绍了组合逻辑电路的各种设计,包括基本门电路(如与非门、异或门等)、多路复用器、加法器、卡诺图简化方法以及在实际应用中的例子,如电话振铃控制器、恒温器和人口计数器等。每个电路都提供了Verilog代码实现。
摘要由CSDN通过智能技术生成

Circuits - Combinational Logic

basic gates

1 wire

Implement the following circuit:

module top_module (
    input in,
    output out);

    assign out = in;
    
endmodule

2 GND

module top_module (
    output out);
	assign out = 0;
endmodule

3 NOR

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

4 another gate

在这里插入图片描述

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

5 two gates

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    input in3,
    output out);

	wire in1_in2_nor;
	
    assign in1_in2_nor = ~ (in1 ^ in2 );
    assign out = in3 ^ in1_in2_nor;
    
endmodule

6 more logic gates

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

7 7420 chip

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

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

numberx3x2x1f
00000
10010
20101
30111
41000
51011
61100
71111

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.

Create a combinational circuit that implements the above truth table.

在这里插入图片描述

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);

    wire [2:0] judge;

    always @(*) begin
        case ({x3,x2,x1})
            3'b000: f = 0;
            3'b001: f = 0;
            3'b010: f = 1;
            3'b011: f = 1;
            3'b100: f = 0;
            3'b101: f = 1;
            3'b110: f = 0;
            3'b111: f = 1;
            default: f = 0;
        endcase
        
    end

endmodule

9 two-bit equality

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 ); 
    assign z = (A == B)? 1 : 0 ;
endmodule

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

11 simple circuit B

在这里插入图片描述

module top_module ( input x, input y, output z );

    always @(*) begin
        case ({x,y})
            2'b00: z = 1;
            2'b01: z = 0;
            2'b10: z = 0;
            2'b11: z = 1;
            default: z = 0;
        endcase
    end

endmodule

12 combine circuits A and B

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.

在这里插入图片描述

module top_module ( input x, input y, output z );

    wire z1,z2,z3,z4;
    wire z12or,z34and;

    circuitA IA1 (x,y,z1);
    circuitB IB1 (x,y,z2);
    circuitA IA2 (x,y,z3);
    circuitB IB2 (x,y,z4);

    assign z12or = z1 | z2;
    assign z34and = z3 & z4;

    assign z = z12or ^ z34and;

endmodule

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

module circuitB ( input x, input y, output z );

    always @(*) begin
        case ({x,y})
            2'b00: z = 1;
            2'b01: z = 0;
            2'b10: z = 0;
            2'b11: z = 1;
            default: z = 0;
        endcase
    end

endmodule

13 Ringer

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 motor = ring & vibrate_mode;
    assign ringer = ring & ~vibrate_mode;
    
endmodule

使用always block的方法:

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);

    always @(*) begin
        if (ring) begin
            if (vibrate_mode) begin
                motor = 1;
            end
            else
                ringer = 1;
        end
        else begin
            motor = 0;
            ringer = 0;
        end
    end

endmodule

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
); 

    assign heater = mode & too_cold;
    assign aircon = ~mode & too_hot;
    assign fan = heater | aircon | fan_on;

endmodule

15 Popcount3

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 );
    
    integer i;
    
    always @(*) begin
        out = 0;
        for ( i = 0 ; i < 3 ; i++ ) begin
            out = out + in[i];
        end
    end
    
endmodule

简化的写法:

module top_module( 
    input [2:0] in,
    output [1:0] out );
    
    assign out = in[0] + in[1] + in[2];
    
endmodule

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

endmodule

17 even longer vectors

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

endmodule

Multiplexers

1 Mux 2 to 1

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 Mux2to1v

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

3 Mux9to1v

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'b 0000: out = a;
            4'b 0001: out = b;
            4'b 0010: out = c;
            4'b 0011: out = d;
            4'b 0100: out = e;
            4'b 0101: out = f;
            4'b 0110: out = g; 
            4'b 0111: out = h;
            4'b 1000: out = i;
            default: out = '1;
            //'1表示全部置1, '0 'x 'z同理
        endcase
    end

endmodule

4 Mux256to1

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

5 Mux256to1v

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],in[4*sel+2],in[4*sel+1],in[4*sel]};
    
endmodule

Arithmetic Circuits

1 Hadd

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 {cout,sum} = a + b;
        
endmodule

2 Fadd

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 {cout,sum} = a + b + cin;
    
endmodule

3 Adder3

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 );
	
    Fadd fadd0 ( a[0], b[0], cin, cout[0], sum[0]);
    Fadd fadd1 ( a[1], b[1], cout[0], cout[1], sum[1]);
    Fadd fadd2 ( a[2], b[2], cout[1], cout[2], sum[2]);
endmodule

module Fadd( 
    input a, b, cin,
    output cout, sum );
    assign {cout,sum} = a + b + cin;
endmodule

4 Adder

Implement the following circuit:

在这里插入图片描述

(“FA” is a full adder)

module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
	
    wire [3:0] cout;
    
    Fadd fadd0 ( x[0], y[0], 0, cout[0], sum[0]);
    Fadd fadd1 ( x[1], y[1], cout[0], cout[1], sum[1]);
    Fadd fadd2 ( x[2], y[2], cout[1], cout[2], sum[2]);
    Fadd fadd3 ( x[3], y[3], cout[2], cout[3], sum[3]);
    
    assign sum[4] = cout[3];
    
endmodule

module Fadd( 
    input a, b, cin,
    output cout, sum );
    assign {cout,sum} = a + b + cin;
endmodule

一种简便的写法:

module top_module (
	input [3:0] x,
	input [3:0] y,
	output [4:0] sum
);

	// 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

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.

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

补码的溢出规律

补码的溢出可以视为两种情况:正溢出和负溢出

正溢出

两个正数相加,产生的进位1覆盖了结果的符号位,导致运算结果为负数

0100 + 0100 = 1000

负溢出

两个负数相加,导致符号位的1变为0。

1001+1010=(1)0011

6 Adder100

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

7 BCDadd4

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 [3:0] c;
    bcd_fadd fadd0( a[3:0], b[3:0], cin, c[0], sum[3:0] );
    bcd_fadd fadd1( a[7:4], b[7:4], c[0], c[1], sum[7:4]);
    bcd_fadd fadd2( a[11:8], b[11:8], c[1], c[2], sum[11:8]);
    bcd_fadd fadd3( a[15:12], b[15:12], c[2], c[3], sum[15:12]);

    assign cout = c[3];

endmodule

Karnaugh map to circuit

1 Kmap1

Implement the circuit described by the Karnaugh map below.

在这里插入图片描述

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

    assign out = (a | b | c);
    
endmodule

2 Kmap2

Implement the circuit described by the Karnaugh map below.

在这里插入图片描述

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

3 Kmap3

Implement the circuit described by the Karnaugh map below.

在这里插入图片描述

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

4 Kmap4

Implement the circuit described by the Karnaugh map below.

在这里插入图片描述

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

    always @(*) begin
        case ({a,b,c,d})
            4'b0100,4'b1000,4'b0001,4'b1101,4'b0111,4'b1011,4'b0010,4'b1110: out = 1;
            default: out = 0; 
        endcase
    end

endmodule

对逻辑式进行化简,可得:

out=a’bc’d’+ab’c’d’+a’b’c’d+abc’d+a’bcd+ab’cd+a’b’cd’+abcd’
=a’b(c⊙d)+ab’(c⊙d)+a’b’(c⊕d)+ab(c⊕d)
=(a⊕d)(c⊙d)+(a⊙d)(c⊕d)
=(a⊕d)⊕(c⊕d)

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

endmodule

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

6 Karnaugh Map

Consider the function f shown in the Karnaugh map below.

在这里插入图片描述

Implement this function. d is don’t-care, which means you may choose to output whatever value is convenient.

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

endmodule

7 Karnaugh Map

Consider the function f shown in the Karnaugh map below. Implement this function.

(The original exam question asked for simplified SOP and POS forms of the function.)

在这里插入图片描述

module top_module (
    input [4:1] x,
    output f
); 

    assign f = ~x[2] & ~x[4] | ~x[1] & x[3] | x[1]& x[2] & x[3] & x[4];

endmodule

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
); 

	always @(*) begin

        mux_in = '0;

        case ({c,d})
            2'b 00: mux_in[2] = 1;
            2'b 01: mux_in[0] = 1;
            2'b 11: begin
                    mux_in[0] = 1;
                    mux_in[3] = 1;
                    end
            2'b 10: begin
                    mux_in[0] = 1;
                    mux_in[2] = 1;
                    end
        endcase
    end

endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值