2021年5月26日 星期三

HBLbits_Verilog Basic Gates

HBLbits_Verilog  Basic Gates

Basic Gates

·        Wire

·        GND

·        NOR

·        Another gate

·        Two gates

·        More logic gates

·        7420 chip

·        Truth tables

·        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

Exams/m2014 q4h

Implement the following circuit:



module top_module (

    input in,

    output out);

        assign out=in;

endmodule

Exams/m2014 q4i

 

Implement the following circuit:



module top_module (

    output out);

        wire w1=1'b0;

    assign out=w1;

endmodule

 

Exams/m2014 q4e

Implement the following circuit:



module top_module (

    input in1,

    input in2,

    output out);

    assign out= ~(in1 | in2) ;

endmodule

Exams/m2014 q4f

Implement the following circuit:



module top_module (

    input in1,

    input in2,

    output out);

    assign out =(in1 & (~in2));

endmodule

Exams/m2014 q4g

Implement the following circuit:



module top_module (

    input in1,

    input in2,

    input in3,

    output out);

        wire w1;

    assign w1= ~(in1 ^in2);

    assign out = (in3 ^ w1);

endmodule

 

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);    //a and-not b

   

endmodule

7420

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

 

Truthtable1

The output column shows what the output should be for each input value.

Row

Inputs

Outputs

number

x3

x2

x1

f

0

0

0

0

0

1

0

0

1

0

2

0

1

0

1

3

0

1

1

1

4

1

0

0

0

5

1

0

1

1

6

1

1

0

0

7

1

1

1

1

The above truth table is for a three-input, one-output function.


module top_module(

    input x3,

    input x2,

    input x1,  // three inputs

    output f   // one output

);

    // f= sigma (2,3,5,7)

    assign f= (~x3 & x2 & ~x1) | (~x3 & x2 & x1) | (x3 & ~x2 & x1) | (x3 & x2 & x1);

endmodule

 

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.

 

y = A'B'C'D' + A'BC'D + AB'CD' + ABCD

z=  sigma (0,5,10,15)



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

   // z= sigma (0,5,10,15)

    assign z= (~A[1] & ~A[0] & ~B[1] & ~B[0]) |

        (~A[1] &  A[0] & ~B[1] &  B[0]) |

        ( A[1] & ~A[0] &  B[1] & ~B[0]) |

        ( A[1] &  A[0] &  B[1] &  B[0]) ;

 

endmodule

 

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

Mt2015 q4a

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

Mt2015 q4b

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);  // sigm (0,3)

endmodule

 

module top_module(

        input x,

        input y,

        output z);

 

        // The simulation waveforms gives you a truth table:

        // y x   z

        // 0 0   1

        // 0 1   0

        // 1 0   0

        // 1 1   1  

        // Two minterms:

        // assign z = (~x & ~y) | (x & y);

 

        // Or: Notice this is an XNOR.

        assign z = ~(x^y);

 

endmodule

Mt2015 q4

 The top-level design consists of two instantiations each of subcircuits A and B, as shown below.



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

Module B is supposed to implement the function  z = (~x & ~y) | (x & y);

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

    wire w1,w2,w3,w4,w5,w6;

   

    mt2015_q4a u0(x,y,w1);

    mt2015_q4b u1(x,y,w2);

   

    mt2015_q4a u3(x,y,w3);

    mt2015_q4b u4(x,y,w4);

   

    assign w5= w1 | w2;

    assign w6= w3 & w4;

    assign z= (w5 ^ w6);

endmodule

 

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

    assign z = (x^y) & x ;

endmodule

 

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

    assign z = (~x & ~y) | (x & y) ;

endmodule    

 

module top_module(

        input x,

        input y,

        output z);

 

        wire o1, o2, o3, o4;

       

        A ia1 (x, y, o1);

        B ib1 (x, y, o2);

        A ia2 (x, y, o3);

        B ib2 (x, y, o4);

       

        assign z = (o1 | o2) ^ (o3 & o4);

 

        // Or you could simplify the circuit including the sub-modules:

        // assign z = x|~y;

       

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

 

Ringer



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.

假設你正在設計一個電路來控制手機的振鈴器和振動電機。當手機來電時(input ring),電路必須把震動( output motor = 1 )或響鈴( output ringer = 1 )打開但不能同時打開當手機處於震動模式時( input vibrate = 1 ),則打開震動( output motor = 1 )。否則打開響鈴。

module top_module(

        input ring,

        input vibrate_mode,

        output ringer,

        output motor

);

       

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

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.

 

 一個冷/熱恒溫控制器可以同時在冬季和夏季對溫度進行調節。

1) 恒溫器可以處於兩種模式之一:制熱(mode = 1)和製冷(mode = 0)。

2) 在制熱模式下,當溫度過低時(too_cold = 1),打開加熱器,但不要使用空調。

3) 在製冷模式下,當溫度過高(too_hot = 1)打開空調,但不要打開加熱器。

4) 當加熱器或空調打開時,也打開風扇使空氣迴圈。

5) 此外,即使加熱器和空調關閉,用戶也可以請求將風扇打開(fan_on = 1)。

 

 

加熱器

空調

風扇

Mode=0 ()

 

 

1

 

Mode=1 ()

 

1

 

 

too_cold=0

 

 

 

 

too_cold=1

 

1

 

 

too_hot=0

 

 

 

 

too_hot=1

 

 

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

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

   

    reg [1:0] out_temp;

    integer i;

    always @(*) begin

        out_temp=2'b00;

        for(i=0;i<=2;i=i+1)

            if (in[i])

                out_temp=out_temp+1;

    end

    assign out=out_temp;

endmodule

 

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

 

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:  For example, out_both[2] should indicate if in[2] and in[3] are both 1. ince in[3] has no neighbour to the left, the answer is obvious so we don't need to know out_both[3].

 

out_any:  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: 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[0] = in[1] & in[0];

    assign out_both[1] = in[2] & in[1];

    assign out_both[2] = in[3] & in[2];

   

    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[1] ^ in[0];

    assign out_different[1] = in[2] ^ in[1];

    assign out_different[2] = in[3] ^ in[2];

    assign out_different[3] = in[0] ^ in[3];

 

endmodule

 

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

 

 

Gatesv100

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

   

1.  /*
   
assign out_both = in[3:1] & in[2:0];

2.      assign out_any = in[3:1] | in[2:0];

3.      assign out_different = {in[0], in[3:1]} ^ in;

4.  */

 

    assign out_both = in[99:1] & in[98:0];

    assign out_any = in[99:1] | in[98:0];

    assign out_different = {in[0], in[99:1]} ^ in[99:0];

 

endmodule


沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...