HDLbits exercises 5 (BASIC GATES节选题)

目录

1\  TRUTHRABLE1

2\  MT2015 EQ2

3\  MT2015 Q4

4\  RINGER

5\  THERMOSTAT

6\  POPCOUNT3

7\  GATESV  


1\  TRUTHRABLE1

在前面的练习中,我们使用简单的逻辑门和几个逻辑门的组合,这些电路是组合电路的例子。

组合电路的意思是电路的输出仅取决于输入,这意味着对于任何给定的输入值,只有一个可能的输出值。因此,描述组合函数行为的一种方法是明确地列出所有可能的输入所对应的输出值,即真值表。

对一个有N个输入的布尔函数而言,有2N种可能的输入组合。真值表的每一行都列出了一个输入组合,因此总有2N行。output列显示了每个输入值对应的输出。

那么我们如何只用标准逻辑门来实现查找表的功能呢?

一种简单的方法是将真值表中所有的真值写为乘积求和项的形式。求和即为或操作,乘积即为与操作。先使用一个N-输入的与门来决定是否输入的向量与真值表匹配,然后再用一个或门来选择满足匹配条件的结果进行输出。

请构建一个模块实现上述真值表的功能。

ERRO:

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);
    assign f=( x1 & x2 ) | ( x1 & x3 ) |((~(x1) & x2) & x3);
endmodule

CORRECT1:

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);
    assign f=(x1&x2&x3)|(x1&x3&(~x2))|(~(x1)&x2&(~x3))|(x1&x2&(~x3));
endmodule

CORRECT2:

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);
    assign assign f = (~x3 & x2) | (x3 & x1);
endmodule

CORRECT3:

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);
    assign  assign f = x3 ? x1 : x2;// You may then notice that this is actually a 2-to-1 mux, selected by x3:
endmodule

HINT:

erro那里我本来是想借用数电知识给真值表画个卡诺图,再列式子,但是我发现根本没必要费那么大劲去干这个事情,直接把真值表输出为1的部分汇总起来然后加一起即可。

2\ MT2015 EQ2

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.

CORRECT1:

module top_module ( input [1:0] A, input [1:0] B, output z ); 

    always @(*)
        begin
            if((A^B)==0)
                z=1;
            else
               z=0;
        end

endmodule

CORRECT2:

module top_module(
    input [1:0] A,
    input [1:0] B,
    output z);

    assign z = (A[1:0]==B[1:0]);    // Comparisons produce a 1 or 0 result.
    // Another option is to use a 16-entry truth table ( {A,B} is 4 bits, with 16 combinations ).
    // There are 4 rows with a 1 result.  0000, 0101, 1010, and 1111.

endmodule

3\ MT2015 Q4

See mt2015_q4a (z = (x^y) & x)and mt2015_q4b (z = ~(x^y))for the submodules used here. The top-level design consists of two instantiations each of subcircuits A and B, as shown below.

HINT:

 You may choose to create this circuit hierarchically using the two submodules as shown in the diagram, or create the same functionality without hierarchy.

虽然correct2简洁一些,但是correct1的写法可以让你练习一下例化的作用。

CORRECT1:

module top_module (input x, input y, output z);
    wire z1,z2,z3,z4;
    wire z12,z34;
    a inst1(x,y,z1);
    b inst2(x,y,z2);
    a inst3(x,y,z3);
    b inst4(x,y,z4);
    assign z12=z1|z2;
    assign z34=z3&z4;
    assign z=z12^z34;
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

CORRECT2:

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

endmodule

4\ RINGER

假设你正在设计一个控制手机铃声和振动电机的电路。每当电话需要从一个来电(输入铃声)响,你的电路必须打开铃声(输出铃声= 1)或电机(输出电机= 1),但不能同时打开。如果手机处于振动模式(input vibrate_mode = 1),打开电机。否则,打开铃声。

试着只使用赋值语句,看看是否可以将问题描述转换为逻辑门的集合。

设计提示:在设计电路时,人们通常必须“向后”思考问题,从输出开始,然后向后到输入。这通常与思考(顺序的,命令式的)编程问题的方式相反,在编程问题中,人们会先查看输入,然后决定操作(或输出)。对于顺序程序,人们通常会认为“如果(输入是___)那么(输出应该是___)”。另一方面,硬件设计师经常认为“(输出应该是___)当(输入)是___时”。

上面的问题描述是用一种适合软件编程的命令式形式写的(如果ring则这样做),所以你必须将它转换成一种更适合硬件实现的声明式形式(assign ringer = ___)。能够在两种风格中思考和转换是硬件设计所需要的最重要的技能之一。

CORRECT:

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

    assign ringer =  ring & (~vibrate_mode);
    assign motor = ring & vibrate_mode;
    
endmodule

5\ 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.

HINT:

When designing circuits, one often has to think of the problem "backwards", starting from the outputs then working backwards towards the inputs. See ringer.

CORRECT:

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=~mode&too_hot;
    assign fan=heater | aircon | fan_on;    

endmodule

6\ 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.

CORRECT:

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

    assign out = in[0]+in[1]+in[2];
endmodule

DEVELOP YOUR MAIND:

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

    // This is a function of 3 inputs. One method is to use a 8-entry truth table:
    // in[2:0] out[1:0]
    // 000      00
    // 001      01
    // 010      01
    // 011      10
    // 100      01
    // 101      10
    // 110      10
    // 111      11
    assign out[0] = (~in[2] & ~in[1] & in[0]) | (~in[2] & in[1] & ~in[0]) | (in[2] & ~in[1] & ~in[0]) | (in[2] & in[1] & in[0]);
    assign out[1] = (in[1] & in[0]) | (in[2] & in[0]) | (in[2] & in[1]);

    // Using the addition operator works too:
    // assign out = in[0]+in[1]+in[2];
    // Yet another method uses behavioural code inside a procedure (combinational always block)
    // to directly implement the truth table:
    /*
    always @(*) begin
        case (in)
            3'd0: out = 2'd0;
            3'd1: out = 2'd1;
            3'd2: out = 2'd1;
            3'd3: out = 2'd2;
            3'd4: out = 2'd1;
            3'd5: out = 2'd2;
            3'd6: out = 2'd2;
            3'd7: out = 2'd3;
        endcase
    end

    */    
endmodule

7\  GATESV  

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

CORRECT:

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wo~he!

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值