\title{Basic Digital Logic Gates with myHDL} \author{Steven K Armour} \maketitle

Table of Contents

Refs

@book{brown_vranesic_2014, place={New York, NY}, edition={3}, title={Fundamentals of digital logic with Verilog design}, publisher={McGraw-Hill}, author={Brown, Stephen and Vranesic, Zvonko G}, year={2014} },

@book{lameres_2017, title={Introduction to logic circuits & logic design with Verilog}, publisher={springer}, author={LaMeres, Brock J}, year={2017} }

Acknowledgments

Author of myHDL Jan Decaluwe and the author of the myHDL Peeker XESS Corp.

Draw.io

Xilinx

Python Liraries utilized


In [1]:
import numpy as np
import pandas as pd
from sympy import *
init_printing()

from myhdl import *
from myhdlpeek import *
import random

#python file of convince tools. Should be located with this notebook
from sympy_myhdl_tools import *

NOT (inverter)

Symbols

The symbols for the NOT gate are shown below

NOT Gate Definition

\begin{definition}\label{def:not} A NOT logic gate; also called an inverter, is a single input, single output gate that will output the boolean value opposite (inverted) to that which was inputted. Its govering equation is given by: $$y_{out}= \bar{x_{in}}$$ or can be repersented (as sympy does ) $$y_{out} = \neg x_{in}$$ \end{definition}

NOT Gate in Sympy and Python


In [2]:
x_in, y_out=symbols('x_in, y_out')
NOTDef1=Eq(y_out, ~x_in)
NOTDef2=Eq(y_out, Not(x_in))
NOTDef1, NOTDef2


Out[2]:
$$\left ( y_{out} = \neg x_{in}, \quad y_{out} = \neg x_{in}\right )$$

In [3]:
NOT_TT=TruthTabelGenrator(NOTDef1)
NOT_TT


Out[3]:
x_in y_out
0 0 1
1 1 0

In [4]:
NOTDef1N=lambdify((x_in), NOTDef1.rhs, dummify=False)
NOTDef1N(False)


Out[4]:
True

In [5]:
pyNOTEq1=lambda x: not x

In [6]:
pyNOTEq1(False)


Out[6]:
True

NOT Gate in myHDL


In [7]:
#create a HDL Module (python function) and its I\O ports
def NotGate(x_in, y_out):
    """Not Logic Gate myHDL Module (function)
    
    Args:
        x_in: bool Input port
        y_out: bool Output port
    
    Returns:
        NOT Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        
        #state the logic operation: in this case negation of the input 'x_in'
        #mapped to the ouput 'y_out' at each Clock cycle
        y_out.next= not x_in
        
    return logic

Issue

At the moment there was a backward compatibility break so that myHDL could call in stuff from lambda functions involving strargs, see: https://github.com/myhdl/myhdl/issues/148

Till this gets fixed no instant lampdafiy into the logic to define the thing but when this gets fixed I am trying that out

myHDL NOT Gate Testing


In [8]:
#create the test signals and intilize value to both be false(0)
x_in, y_out=[Signal(bool(0)) for _ in range(2)]
#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()
#load and name the signals to watch into peeker
Peeker(x_in, 'x_in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=NotGate(x_in=x_in, y_out=y_out)
inputs=[x_in]
sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='NOT gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [10]:
MakeDFfromPeeker(Peeker.to_wavejson())


Out[10]:
x_in y_out
0 0 1
1 1 0
2 0 1

myHDL NOT Gate to HDL


In [11]:
toVerilog(NotGate, x_in, y_out)
toVHDL(NotGate, x_in, y_out)
_=VerilogTextReader('NotGate')


***Verilog modual from NotGate.v***

 // File: NotGate.v
// Generated by MyHDL 0.9.0
// Date: Mon Oct  9 02:48:20 2017


`timescale 1ns/10ps

module NotGate (
    x_in,
    y_out
);
// Not Logic Gate myHDL Module (function)
// 
// Args:
//     x_in: bool Input port
//     y_out: bool Output port
// 
// Returns:
//     NOT Combo logic operation
//     

input x_in;
output y_out;
wire y_out;







assign y_out = (!x_in);

endmodule


In [12]:
_=VHDLTextReader('NotGate')


***VHDL modual from NotGate.vhd***

 -- File: NotGate.vhd
-- Generated by MyHDL 0.9.0
-- Date: Mon Oct  9 02:48:20 2017


library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use std.textio.all;

use work.pck_myhdl_090.all;

entity NotGate is
    port (
        x_in: in std_logic;
        y_out: out std_logic
    );
end entity NotGate;
-- Not Logic Gate myHDL Module (function)
-- 
-- Args:
--     x_in: bool Input port
--     y_out: bool Output port
-- 
-- Returns:
--     NOT Combo logic operation
--     

architecture MyHDL of NotGate is






begin






y_out <= stdl((not bool(x_in)));

end architecture MyHDL;

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our NOT Gate from the synthesised verilog code

AND

Symbols

The symbols for an AND gate are shown below

AND Gate Definition

\begin{definition} An AND gate is a multi input single output logic gate that gives the multiplication of the boolean inputs as its output. $$y_{\text{out}}=\prod_{i=1}^{N\geq 2} x_{i\text{ in} }$$ In more compact notation it is represented as (for a 2-input): $$y_{\text{out}}=x_{1\text{ in} } \cdot x_{2\text{ in} }$$ Which can also be written (as sympy does) as: $$y_{\text{out}}=x_{1\text{ in} } \wedge x_{2\text{ in} }$$ \end{definition}

AND Gate in Sympy and Python


In [13]:
x_1in, x_2in, y_out=symbols('x_1in, x_2in, y_out')
AND2Def1=Eq(y_out, x_1in & x_2in)
AND2Def2=Eq(y_out, And(x_1in , x_2in))
AND2Def1, AND2Def2


Out[13]:
$$\left ( y_{out} = x_{1in} \wedge x_{2in}, \quad y_{out} = x_{1in} \wedge x_{2in}\right )$$

In [14]:
AND2_TT=TruthTabelGenrator(AND2Def1)
AND2_TT


Out[14]:
x_1in x_2in y_out
0 0 0 0
1 0 1 0
2 1 0 0
3 1 1 1

In [15]:
AND2Def2N=lambdify((x_1in, x_2in), AND2Def2.rhs, dummify=False)
AND2Def2N(True, False)


Out[15]:
False

In [16]:
x_1in, x_2in, x_3in, y_out=symbols('x_1in, x_2in, x_3in, y_out')
AND3Def1=Eq(y_out, x_1in & x_2in & x_3in)
AND3Def2=Eq(y_out, And(x_1in , x_2in, x_3in))
AND3Def1, AND3Def2


Out[16]:
$$\left ( y_{out} = x_{1in} \wedge x_{2in} \wedge x_{3in}, \quad y_{out} = x_{1in} \wedge x_{2in} \wedge x_{3in}\right )$$

In [17]:
AND3_TT=TruthTabelGenrator(AND3Def2)
AND3_TT


Out[17]:
x_1in x_2in x_3in y_out
0 0 0 0 0
1 0 0 1 0
2 0 1 0 0
3 0 1 1 0
4 1 0 0 0
5 1 0 1 0
6 1 1 0 0
7 1 1 1 1

In [18]:
AND3Def1N=lambdify((x_1in, x_2in, x_3in), AND3Def1.rhs, dummify=False)
#not working no idea
#AND3Def1N(True, True, True)

In [19]:
pyAND2Eq2=lambda x1, x2: x1 & x2
pyAND2Eq2=lambda x1, x2: x1 and x2
pyAND3Eq1=lambda x1, x2, x3: x1 & x2 & x3
pyAND3Eq2=lambda x1, x2, x3: x1 and x2 and x3

In [20]:
pyAND2Eq2(0,0), pyAND2Eq2(0,1), pyAND3Eq1(1,1,1), pyAND3Eq1(0,1,1)


Out[20]:
$$\left ( 0, \quad 0, \quad 1, \quad 0\right )$$

myHDL Two input AND Gate and Testing


In [21]:
#create a HDL Module (python function) and its I\O ports
def And2Gate(x_1in, x_2in, y_out):
    """AND Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= x_1in and x_2in
        
    return logic

In [22]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, y_out=[Signal(bool(0)) for _ in range(3)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=And2Gate(x_1in=x_1in, x_2in=x_2in, y_out=y_out)

inputs=[x_1in, x_2in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='AND 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [23]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[23]:
x_1in x_2in y_out
0 0 0 0
1 0 1 0
2 1 0 0
3 1 1 1

myHDL Three Input AND Gate and Testing


In [24]:
#create a myHDL Module (python function) and its I\O ports
def And3Gate(x_1in, x_2in, x_3in, y_out):
    """AND Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        x_3in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= x_1in and x_2in and x_3in
        
    return logic

In [25]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, x_3in, y_out=[Signal(bool(0)) for _ in range(4)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in'); Peeker(x_3in, 'x_3in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=And3Gate(x_1in=x_1in, x_2in=x_2in, x_3in=x_3in, y_out=y_out)

inputs=[x_1in, x_2in, x_3in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='AND 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [26]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[26]:
x_1in x_2in x_3in y_out
0 0 0 0 0
1 0 0 1 0
2 0 1 0 0
3 0 1 1 0
4 1 0 0 0
5 1 0 1 0
6 1 1 0 0
7 1 1 1 1

myHDL Three Input AND Gate HDL Synthesis


In [27]:
toVerilog(And3Gate, x_1in, x_2in, x_3in, y_out)
#toVHDL(And3Gate, x_1in, x_2in, x_3in y_out)
_=VerilogTextReader('And3Gate')


***Verilog modual from And3Gate.v***

 // File: And3Gate.v
// Generated by MyHDL 0.9.0
// Date: Mon Oct  9 02:48:50 2017


`timescale 1ns/10ps

module And3Gate (
    x_1in,
    x_2in,
    x_3in,
    y_out
);
// AND Logic Gate myHDL Module (function)
// 
// Args:
//     x_1in: bool Input port
//     x_2in: bool Input port
//     x_3in: bool Input port
//     y_out: bool Output port
// 
// Returns:
//     AND Combo logic operation
//     

input x_1in;
input x_2in;
input x_3in;
output y_out;
wire y_out;







assign y_out = (x_1in && x_2in && x_3in);

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL three input AND gate's verilog code

OR

Symbols

The Symbols for an OR gate are shown below

OR Gate Definition

\begin{definition}\label{def:or} An OR gate is a multi input single output logic gate that gives the sum of the boolean inputs as its output $$y_{\text{out}}=\sum_{i=1}^{N\geq 2} x_{i\text{ in}}$$ In more compact notation it is represented as (for a 2-input): $$y_{\text{out}}=x_{1\text{ in} } + x_{2\text{ in} }$$ Which can also be written (as sympy does) as: $$y_{\text{out}}=x_{1\text{ in} } \vee x_{2\text{ in} }$$ \end{definition}

OR Gate in Sympy and Python


In [28]:
x_1in, x_2in, y_out=symbols('x_1in, x_2in, y_out')
OR2Def1=Eq(y_out, x_1in | x_2in)
OR2Def2=Eq(y_out, Or(x_1in , x_2in))
OR2Def1, OR2Def2


Out[28]:
$$\left ( y_{out} = x_{1in} \vee x_{2in}, \quad y_{out} = x_{1in} \vee x_{2in}\right )$$

In [29]:
OR2_TT=TruthTabelGenrator(OR2Def2)
OR2_TT


Out[29]:
x_1in x_2in y_out
0 0 0 0
1 0 1 1
2 1 0 1
3 1 1 1

In [30]:
OR2Def1N=lambdify((x_1in, x_2in), OR2Def1.rhs, dummify=False)
OR2Def1N(True, False)


Out[30]:
True

In [31]:
x_1in, x_2in, x_3in, y_out=symbols('x_1in, x_2in, x_3in, y_out')
OR3Def1=Eq(y_out, x_1in | x_2in | x_3in)
OR3Def2=Eq(y_out, Or(x_1in , x_2in, x_3in))
OR3Def1, OR3Def2


Out[31]:
$$\left ( y_{out} = x_{1in} \vee x_{2in} \vee x_{3in}, \quad y_{out} = x_{1in} \vee x_{2in} \vee x_{3in}\right )$$

In [32]:
OR3_TT=TruthTabelGenrator(OR3Def1)
OR3_TT


Out[32]:
x_1in x_2in x_3in y_out
0 0 0 0 0
1 0 0 1 1
2 0 1 0 1
3 0 1 1 1
4 1 0 0 1
5 1 0 1 1
6 1 1 0 1
7 1 1 1 1

In [33]:
OR3Def2N=lambdify((x_1in, x_2in, x_3in), OR3Def2.rhs, dummify=False)
#yeah WTH
#OR3Def2N(False, False, False)

In [34]:
pyOR2Eq1=lambda x1, x2: x1 | x2
pyOR2Eq2=lambda x1, x2: x1 or x2
pyOR3Eq1=lambda x1, x2, x3: x1 | x2 | x3
pyOR3Eq2=lambda x1, x2, x3: x1 or x2 or x3

In [35]:
pyOR2Eq1(0, 0), pyOR2Eq2(1,1), pyOR3Eq1(1,1,0), pyOR3Eq2(0,1,0)


Out[35]:
$$\left ( 0, \quad 1, \quad 1, \quad 1\right )$$

myHDL Two Input OR Gate and Testing


In [36]:
#create a HDL Module (python function) and its I\O ports
def Or2Gate(x_1in, x_2in, y_out):
    """AND Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= x_1in or x_2in
        
    return logic

In [37]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, y_out=[Signal(bool(0)) for _ in range(3)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=Or2Gate(x_1in=x_1in, x_2in=x_2in, y_out=y_out)

inputs=[x_1in, x_2in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='OR 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [40]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[40]:
x_1in x_2in y_out
0 0 0 0
1 0 1 1
2 1 0 1
3 1 1 1

myHDL Three Input OR Gate and Testing


In [41]:
#create a HDL Module (python function) and its I\O ports
def Or3Gate(x_1in, x_2in, x_3in, y_out):
    """Or Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        x_3in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= x_1in or x_2in or x_3in
        
    return logic

In [42]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, x_3in, y_out=[Signal(bool(0)) for _ in range(4)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in'); Peeker(x_3in, 'x_3in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=Or3Gate(x_1in=x_1in, x_2in=x_2in, x_3in=x_3in, y_out=y_out)

inputs=[x_1in, x_2in, x_3in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='OR 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [43]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[43]:
x_1in x_2in x_3in y_out
0 0 0 0 0
1 0 0 1 1
2 0 1 0 1
3 0 1 1 1
4 1 0 0 1
5 1 0 1 1
6 1 1 0 1
7 1 1 1 1

myHDL Three Input AND Gate HDL Synthesis


In [44]:
toVerilog(Or3Gate, x_1in, x_2in, x_3in, y_out)
#toVHDL(And3Gate, x_1in, x_2in, x_3in y_out)
_=VerilogTextReader('Or3Gate')


***Verilog modual from Or3Gate.v***

 // File: Or3Gate.v
// Generated by MyHDL 0.9.0
// Date: Mon Oct  9 02:49:49 2017


`timescale 1ns/10ps

module Or3Gate (
    x_1in,
    x_2in,
    x_3in,
    y_out
);
// Or Logic Gate myHDL Module (function)
// 
// Args:
//     x_1in: bool Input port
//     x_2in: bool Input port
//     x_3in: bool Input port
//     y_out: bool Output port
// 
// Returns:
//     AND Combo logic operation
//     

input x_1in;
input x_2in;
input x_3in;
output y_out;
wire y_out;







assign y_out = (x_1in || x_2in || x_3in);

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL three input OR gate's verilog code

DeMorgan's theorem

finding the conjugate logical expression

NAND

negated and, negated multiplication, sum of negated inputs

Symbols

NAND Gate Definition

\begin{definition} A NAND gate is multi input single output logic gate that gives the negation of the multiplication of the boolean inputs at its output and is thus the DeMorgan conjugate of the AND Gate $$y_{\text{out}}=\bar{\prod_{i=1}^{N\geq 2} x_{i\text{ in} }}=\sum_{i=1}^{N\geq 2} \bar{x_{i\text{ in} }}$$ In more compact notation it is represented as (for a 2-input): $$y_{\text{out}}=\bar{x_{1\text{ in} }} + \bar{x_{2\text{ in} }}$$ Which can also be written (as sympy does) as: $$y_{\text{out}}=\neg(x_{1\text{ in} } \wedge x_{2\text{ in} })=\neg x_{1\text{ in} } \vee \neg x_{2\text{ in} }$$ \end{definition}

NAND Gate in Sympy and Python


In [45]:
x_1in, x_2in, y_out=symbols('x_1in, x_2in, y_out')
NAND2Def0=Eq(y_out, Nand(x_1in, x_2in))
NAND2Def1=Eq(y_out, ~(x_1in & x_2in))
NAND2Def2=Eq(y_out, Not(And(x_1in , x_2in)))
NAND2Def3=simplify(NAND2Def2) #DeMorgan equivlinacy
NAND2Def0, NAND2Def1, NAND2Def2, NAND2Def3


Out[45]:
$$\left ( y_{out} = \neg (x_{1in} \wedge x_{2in}), \quad y_{out} = \neg (x_{1in} \wedge x_{2in}), \quad y_{out} = \neg (x_{1in} \wedge x_{2in}), \quad y_{out} = \neg x_{1in} \vee \neg x_{2in}\right )$$

In [46]:
NAND2_TT=TruthTabelGenrator(NAND2Def0)
NAND2_TT


Out[46]:
x_1in x_2in y_out
0 0 0 1
1 0 1 1
2 1 0 1
3 1 1 0

In [47]:
NAND2_DME_TT=TruthTabelGenrator(NAND2Def2)
NAND2_DME_TT


Out[47]:
x_1in x_2in y_out
0 0 0 1
1 0 1 1
2 1 0 1
3 1 1 0

In [48]:
NAND2_TT.equals(NAND2_DME_TT)


Out[48]:
True

In [49]:
NAND2Def3N=lambdify((x_1in, x_2in), NAND2Def3.rhs, dummify=False)
NAND2Def3N(True, True)


Out[49]:
False

In [50]:
x_1in, x_2in, x_3in, y_out=symbols('x_1in, x_2in, x_3in, y_out')
NAND3Def0=Eq(y_out, Nand(x_1in, x_2in, x_3in))
NAND3Def1=Eq(y_out, ~(x_1in & x_2in & x_3in))
NAND3Def2=Eq(y_out, Not(And(x_1in , x_2in, x_3in)))
NAND3Def3=simplify(NAND3Def1) #DeMorgan equivlinacy
NAND3Def0, NAND3Def1, NAND3Def2, NAND3Def3


Out[50]:
$$\left ( y_{out} = \neg (x_{1in} \wedge x_{2in} \wedge x_{3in}), \quad y_{out} = \neg (x_{1in} \wedge x_{2in} \wedge x_{3in}), \quad y_{out} = \neg (x_{1in} \wedge x_{2in} \wedge x_{3in}), \quad y_{out} = \neg x_{1in} \vee \neg x_{2in} \vee \neg x_{3in}\right )$$

In [51]:
NAND3_TT=TruthTabelGenrator(NAND3Def0)
NAND3_TT


Out[51]:
x_1in x_2in x_3in y_out
0 0 0 0 1
1 0 0 1 1
2 0 1 0 1
3 0 1 1 1
4 1 0 0 1
5 1 0 1 1
6 1 1 0 1
7 1 1 1 0

In [52]:
NAND3_DME_TT=TruthTabelGenrator(NAND3Def1)
NAND3_TT.equals(NAND3_DME_TT)


Out[52]:
True

In [53]:
NAND3Def3N=lambdify((x_1in, x_2in, x_3in), NAND3Def3, dummify=False)
#again WTH
#NAND3Def3N(1, 0, 1)

In [54]:
#DoNotTrust: pyNAND2Eq1=lambda x1, x2: ~(x1 & x2)
pyNAND2Eq2=lambda x1, x2: not(x1 and x2)
#DoNotTrust: pyNAND2Eq3=lambda x1, x2: ~x1 | ~x2
pyNAND2Eq4=lambda x1, x2: not x1 or not x2

#DoNotTrust:pyNAND3Eq1=lambda x1, x2, x3: ~(x1 & x2 & x3)
pyNAND3Eq2=lambda x1, x2, x3: not(x1 and x2 and x3)
#DoNotTrust:pyNAND3Eq3=lambda x1, x2, x3: ~x1 | ~x2 | ~x3
pyNAND3Eq4=lambda x1, x2, x3: not x1 or not x2 or not x3

In [55]:
pyNAND2Eq2(0,1), pyNAND2Eq4(1,1), pyNAND3Eq2(0,1,0), pyNAND3Eq4(0,0,0)


Out[55]:
(True, False, True, True)

myHDL Two Input NAND Gate and Testing


In [56]:
#create a HDL Module (python function) and its I\O ports
def Nand2Gate(x_1in, x_2in, y_out):
    """AND Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= not(x_1in and x_2in)
        
    return logic

In [57]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, y_out=[Signal(bool(0)) for _ in range(3)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=Nand2Gate(x_1in=x_1in, x_2in=x_2in, y_out=y_out)

inputs=[x_1in, x_2in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='NAND 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [58]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[58]:
x_1in x_2in y_out
0 0 0 1
1 0 1 1
2 1 0 1
3 1 1 0

myHDL Three Input NAND Gate and Testing


In [59]:
#create a HDL Module (python function) and its I\O ports
def Nand3Gate(x_1in, x_2in, x_3in, y_out):
    """AND Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        x_3in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= (not x_1in) or  (not x_2in) or (not x_3in)
        
    return logic

In [60]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, x_3in, y_out=[Signal(bool(0)) for _ in range(4)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in'); Peeker(x_3in, 'x_3in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=Nand3Gate(x_1in=x_1in, x_2in=x_2in, x_3in=x_3in, y_out=y_out)

inputs=[x_1in, x_2in, x_3in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='NAND 3 gate simulation',
             ## myHDL Three Input AND Gate HDL Synthesis
     caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [61]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[61]:
x_1in x_2in x_3in y_out
0 0 0 0 1
1 0 0 1 1
2 0 1 0 1
3 0 1 1 1
4 1 0 0 1
5 1 0 1 1
6 1 1 0 1
7 1 1 1 0

myHDL Three Input NAND Gate HDL Synthesis


In [62]:
toVerilog(Nand3Gate, x_1in, x_2in, x_3in, y_out)
#toVHDL(And3Gate, x_1in, x_2in, x_3in y_out)
_=VerilogTextReader('Nand3Gate')


***Verilog modual from Nand3Gate.v***

 // File: Nand3Gate.v
// Generated by MyHDL 0.9.0
// Date: Mon Oct  9 02:50:21 2017


`timescale 1ns/10ps

module Nand3Gate (
    x_1in,
    x_2in,
    x_3in,
    y_out
);
// AND Logic Gate myHDL Module (function)
// 
// Args:
//     x_1in: bool Input port
//     x_2in: bool Input port
//     x_3in: bool Input port
//     y_out: bool Output port
// 
// Returns:
//     AND Combo logic operation
//     

input x_1in;
input x_2in;
input x_3in;
output y_out;
wire y_out;







assign y_out = ((!x_1in) || (!x_2in) || (!x_3in));

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL three input NAND gate's verilog code

NOR

negated or, negated addition, product of negated inputs

Symbols

NOR Gate Definition

\begin{definition}\label{def:nor} A NOR gate is a multi input single output logic gate that gives the negation of the sum of the boolean inputs at its output and is thus the DeMorgan conjugate of the OR Gate $$y_{\text{out}}=\bar{\sum_{i=1}^{N\geq 2} x_{i\text{ in}}}=\prod_{i=1}^{N\geq 2} \bar{x_{i\text{ in}}}$$ In more compact notation it is represented as (for a 2-input): $$y_{\text{out}}=\bar{x_{1\text{ in} } + x_{2\text{ in} }}=\bar{x_{1\text{ in} }} \cdot \bar{x_{2\text{ in} }}$$ Which can also be written (as sympy does) as: $$y_{\text{out}}=\neg(x_{1\text{ in} } \vee x_{2\text{ in} })=\neg x_{1\text{ in} } \wedge \neg x_{2\text{ in} }$$ \end{definition}

NOR Gate in Sympy and Python


In [63]:
x_1in, x_2in, y_out=symbols('x_1in, x_2in, y_out')
NOR2Def0=Eq(y_out, Nor(x_1in, x_2in))
NOR2Def1=Eq(y_out, ~(x_1in | x_2in))
NOR2Def2=Eq(y_out, Not(Or(x_1in , x_2in)))
NOR2Def3=simplify(NOR2Def2) #DeMorgan equivlinacy
NOR2Def0, NOR2Def1, NOR2Def2, NOR2Def3


Out[63]:
$$\left ( y_{out} = \neg (x_{1in} \vee x_{2in}), \quad y_{out} = \neg (x_{1in} \vee x_{2in}), \quad y_{out} = \neg (x_{1in} \vee x_{2in}), \quad y_{out} = \neg x_{1in} \wedge \neg x_{2in}\right )$$

In [64]:
NOR2_TT=TruthTabelGenrator(NOR2Def0)
NOR2_TT


Out[64]:
x_1in x_2in y_out
0 0 0 1
1 0 1 0
2 1 0 0
3 1 1 0

In [65]:
NOR2_DME_TT=TruthTabelGenrator(NOR2Def3)
NOR2_TT.equals(NOR2_DME_TT)


Out[65]:
True

In [66]:
NOR2Def2N=lambdify((x_1in, x_2in), NOR2Def2.rhs, dummify=False)
NOR2Def2N(0,1)


Out[66]:
False

In [67]:
x_1in, x_2in, x_3in, y_out=symbols('x_1in, x_2in, x_3in, y_out')
NOR3Def0=Eq(y_out, Nor(x_1in, x_2in, x_3in))
NOR3Def1=Eq(y_out, ~(x_1in | x_2in | x_3in))
NOR3Def2=Eq(y_out, Not(Or(x_1in , x_2in, x_3in)))
NOR3Def3=simplify(NOR3Def1) #DeMorgan equivlinacy
NOR3Def0, NOR3Def1, NOR3Def2, NOR3Def3


Out[67]:
$$\left ( y_{out} = \neg (x_{1in} \vee x_{2in} \vee x_{3in}), \quad y_{out} = \neg (x_{1in} \vee x_{2in} \vee x_{3in}), \quad y_{out} = \neg (x_{1in} \vee x_{2in} \vee x_{3in}), \quad y_{out} = \neg x_{1in} \wedge \neg x_{2in} \wedge \neg x_{3in}\right )$$

In [68]:
NOR3_TT=TruthTabelGenrator(NOR3Def0)
NOR3_TT


Out[68]:
x_1in x_2in x_3in y_out
0 0 0 0 1
1 0 0 1 0
2 0 1 0 0
3 0 1 1 0
4 1 0 0 0
5 1 0 1 0
6 1 1 0 0
7 1 1 1 0

In [69]:
NOR3_DME_TT=TruthTabelGenrator(NOR3Def1)
NOR3_TT.equals(NOR3_DME_TT)


Out[69]:
True

In [70]:
NOR3Def2N=lambdify((x_1in, x_2in, x_3in), NOR3Def2.rhs, dummify=False)
#Again WTH
#NOR3Def2N(False, False, False)

In [71]:
#DoNotTrust: pyNOR2Eq1=lambda x1, x2: ~(x1 | x2)
pyNOR2Eq2=lambda x1, x2: not(x1 or x2)
#DoNotTrust: pyNOR2Eq3=lambda x1, x2: ~x1 & ~x2
pyNOR2Eq4=lambda x1, x2: not x1 and not x2

#DoNotTrust: pyNOR3Eq1=lambda x1, x2, x3: ~(x1 | x2 | x3)
pyNOR3Eq2=lambda x1, x2, x3: not(x1 or x2 or x3)
#DoNotTrust: pyNOR3Eq3=lambda x1, x2, x3: ~x1 & ~x2 & ~x3
pyNOR3Eq4=lambda x1, x2, x3: not x1 and not x2 and not x3

In [72]:
pyNOR2Eq2(0,1), pyNOR2Eq4(1,0), pyNOR3Eq2(0,0,0), pyNOR3Eq4(1,0,1)


Out[72]:
(False, False, True, False)

myHDL Two Input NOR Gate and Testing


In [73]:
#create a HDL Module (python function) and its I\O ports
def Nor2Gate(x_1in, x_2in, y_out):
    """AND Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        y_out: bool Output port
    
    Returns:
        AND Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= not(x_1in or x_2in)
        
    return logic

In [74]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, y_out=[Signal(bool(0)) for _ in range(3)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=Nor2Gate(x_1in=x_1in, x_2in=x_2in, y_out=y_out)

inputs=[x_1in, x_2in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='NOR 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [75]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[75]:
x_1in x_2in y_out
0 0 0 1
1 0 1 0
2 1 0 0
3 1 1 0

myHDL Two Input NOR Gate HDL Synthesis


In [76]:
toVerilog(Nor2Gate, x_1in, x_2in, y_out)
#toVHDL(Nor2Gate, x_1in, x_2in y_out)
_=VerilogTextReader('Nor2Gate')


***Verilog modual from Nor2Gate.v***

 // File: Nor2Gate.v
// Generated by MyHDL 0.9.0
// Date: Mon Oct  9 02:50:55 2017


`timescale 1ns/10ps

module Nor2Gate (
    x_1in,
    x_2in,
    y_out
);
// AND Logic Gate myHDL Module (function)
// 
// Args:
//     x_1in: bool Input port
//     x_2in: bool Input port
//     y_out: bool Output port
// 
// Returns:
//     AND Combo logic operation
//     

input x_1in;
input x_2in;
output y_out;
wire y_out;







assign y_out = (!(x_1in || x_2in));

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL two input NOR gate's verilog code

XOR

The Exclusive OR

Symbols

The Symbols for a XOR gate are show below

XOR Gate Definition

need to come up with this

XOR Gate in Sympy and Python


In [77]:
x_1in, x_2in, y_out=symbols('x_1in, x_2in, y_out')
XOR2Def0=Eq(y_out, Xor(x_1in, x_2in))
XOR2Def1=Eq(y_out, x_1in ^ x_2in)
XOR2Def2=Eq(y_out, ~x_1in&x_2in | x_1in& ~x_2in)
XOR2Def0, XOR2Def1, XOR2Def2, simplify_logic(XOR2Def2)


Out[77]:
$$\left ( y_{out} = x_{1in} \veebar x_{2in}, \quad y_{out} = x_{1in} \veebar x_{2in}, \quad y_{out} = \left(x_{1in} \wedge \neg x_{2in}\right) \vee \left(x_{2in} \wedge \neg x_{1in}\right), \quad y_{out} = \left(x_{1in} \wedge \neg x_{2in}\right) \vee \left(x_{2in} \wedge \neg x_{1in}\right)\right )$$

In [78]:
XOR2_TT=TruthTabelGenrator(XOR2Def0)
XOR2_TT


Out[78]:
x_1in x_2in y_out
0 0 0 0
1 0 1 1
2 1 0 1
3 1 1 0

In [79]:
XOR2_TT2=TruthTabelGenrator(XOR2Def2)
XOR2_TT.equals(XOR2_TT2)


Out[79]:
True

In [80]:
XOR2Def1N=lambdify((x_1in, x_2in), XOR2Def1, dummify=False)
#oh come on
#XOR2Def1N(0, 1)

In [81]:
pyXOR2Eq1=lambda x1, x2: x1^x2
pyXOR2Eq1(1, 1)


Out[81]:
$$0$$

myHDL Two Input XOR Gate and Testing


In [82]:
#create a HDL Module (python function) and its I\O ports
def Xor2Gate(x_1in, x_2in, y_out):
    """Or Logic Gate myHDL Module (function)
    
    Args:
        x_1in: bool Input port
        x_2in: bool Input port
        y_out: bool Output port
    
    Returns:
        XOR Combo logic operation
        
    """
    #define what this module is to do
    
    #myHDL built in decorator to say the function is exuiquated on each
    #clock cycle
    @always_comb
    def logic():
        y_out.next= x_1in ^ x_2in 
        
    return logic

In [83]:
#create the test signals and intilize value to both be false(0)
x_1in, x_2in, y_out=[Signal(bool(0)) for _ in range(3)]

#Peeker is helper libary for viewing wavefrom outputs and run the sim inside
#jupyter notebooks
#clear any previeese data loaded into peeker
Peeker.clear()

#load and name the signals to watch into peeker
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(y_out, 'y_out')

#make an instatince of the NotGate as the DUT
DUT=Xor2Gate(x_1in=x_1in, x_2in=x_2in, y_out=y_out)

inputs=[x_1in, x_2in]

sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='XOR 2 gate simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


<class 'myhdl.StopSimulation'>: No more events

In [84]:
MakeDFfromPeeker(Peeker.to_wavejson(start_time=0, stop_time=2**len(inputs) -1))


Out[84]:
x_1in x_2in y_out
0 0 0 0
1 0 1 1
2 1 0 1
3 1 1 0

myHDL Two Input XOR gate HDL Synthesis


In [85]:
toVerilog(Xor2Gate, x_1in, x_2in, y_out)
#toVHDL(Xor2Gate, x_1in, x_2in y_out)
_=VerilogTextReader('Xor2Gate')


***Verilog modual from Xor2Gate.v***

 // File: Xor2Gate.v
// Generated by MyHDL 0.9.0
// Date: Mon Oct  9 02:51:19 2017


`timescale 1ns/10ps

module Xor2Gate (
    x_1in,
    x_2in,
    y_out
);
// Or Logic Gate myHDL Module (function)
// 
// Args:
//     x_1in: bool Input port
//     x_2in: bool Input port
//     y_out: bool Output port
// 
// Returns:
//     XOR Combo logic operation
//     

input x_1in;
input x_2in;
output y_out;
wire y_out;







assign y_out = (x_1in ^ x_2in);

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL two input NOR gate's verilog code

!Need to add the RTL schematic

Min & Max Terms, SOP POS

KMaps

Examples of boolean expressions

Exsample of a 2 bit 7 Segment Display Logic Synthesis


In [88]:
x1, x2, x3, x4=symbols('x_1, x_2, x_3, x_4')
lits=[x1, x2, x3, x4]

In [89]:
terms=set(list(range(2**len(lits)))); terms


Out[89]:
$$\left\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15\right\}$$

In [90]:
DCterms=set(list(range(10, 15+1))); DCterms


Out[90]:
$$\left\{10, 11, 12, 13, 14, 15\right\}$$

In [91]:
usableTerms=terms-DCterms; usableTerms


Out[91]:
$$\left\{0, 1, 2, 3, 4, 5, 6, 7, 8, 9\right\}$$

In [92]:
SOPfromUT=lambda POSterms: usableTerms-POSterms

In [93]:
aPOSterms={1,4}; aSOPterms=SOPfromUT(aPOSterms)
bPOSterms={5,6}; bSOPterms=SOPfromUT(bPOSterms)
cPOSterms={2}; cSOPterms=SOPfromUT(cPOSterms)
dPOSterms={2,4,7}; dSOPterms=SOPfromUT(dPOSterms)
ePOSterms={1,3,4,5,7,9}; eSOPterms=SOPfromUT(ePOSterms)
fPOSterms={1,2,3,7}; fSOPterms=SOPfromUT(fPOSterms)
gPOSterms={0,1,7}; gSOPterms=SOPfromUT(gPOSterms)

In [94]:
aSOP, aPOS=POS_SOPformCalcater(lits, aSOPterms, aPOSterms, DCterms)
bSOP, bPOS=POS_SOPformCalcater(lits, bSOPterms, bPOSterms, DCterms)
cSOP, cPOS=POS_SOPformCalcater(lits, cSOPterms, cPOSterms, DCterms)
dSOP, dPOS=POS_SOPformCalcater(lits, dSOPterms, dPOSterms, DCterms)
eSOP, ePOS=POS_SOPformCalcater(lits, eSOPterms, ePOSterms, DCterms)
fSOP, fPOS=POS_SOPformCalcater(lits, fSOPterms, fPOSterms, DCterms)
gSOP, gPOS=POS_SOPformCalcater(lits, gSOPterms, gPOSterms, DCterms)

In [95]:
aSOP, aPOS


Out[95]:
$$\left ( x_{1} \vee x_{3} \vee \left(x_{2} \wedge x_{4}\right) \vee \left(\neg x_{2} \wedge \neg x_{4}\right), \quad \neg x_{1} \wedge \neg x_{3} \wedge \left(x_{2} \vee x_{4}\right) \wedge \left(\neg x_{2} \vee \neg x_{4}\right)\right )$$

In [96]:
bSOP, bPOS


Out[96]:
$$\left ( \left(x_{3} \wedge x_{4}\right) \vee \left(\neg x_{3} \wedge \neg x_{4}\right) \vee \neg x_{2}, \quad x_{2} \wedge \left(x_{3} \vee x_{4}\right) \wedge \left(\neg x_{3} \vee \neg x_{4}\right)\right )$$

In [97]:
cSOP, cPOS


Out[97]:
$$\left ( x_{2} \vee x_{4} \vee \neg x_{3}, \quad x_{3} \wedge \neg x_{2} \wedge \neg x_{4}\right )$$

In [98]:
dSOP, dPOS


Out[98]:
$$\left ( \left(x_{4} \wedge \neg x_{2}\right) \vee \left(x_{4} \wedge \neg x_{3}\right) \vee \left(\neg x_{2} \wedge \neg x_{3}\right) \vee \left(x_{2} \wedge x_{3} \wedge \neg x_{4}\right), \quad \left(x_{2} \vee x_{3}\right) \wedge \left(x_{2} \vee \neg x_{4}\right) \wedge \left(x_{3} \vee \neg x_{4}\right) \wedge \left(x_{4} \vee \neg x_{2} \vee \neg x_{3}\right)\right )$$

In [99]:
eSOP, ePOS


Out[99]:
$$\left ( \neg x_{4} \wedge \left(x_{3} \vee \neg x_{2}\right), \quad x_{4} \vee \left(x_{2} \wedge \neg x_{3}\right)\right )$$

In [100]:
fSOP, fPOS


Out[100]:
$$\left ( x_{1} \vee \left(x_{2} \wedge \neg x_{3}\right) \vee \left(x_{2} \wedge \neg x_{4}\right) \vee \left(\neg x_{3} \wedge \neg x_{4}\right), \quad \neg x_{1} \wedge \left(x_{3} \vee x_{4}\right) \wedge \left(x_{3} \vee \neg x_{2}\right) \wedge \left(x_{4} \vee \neg x_{2}\right)\right )$$

In [101]:
gSOP, gPOS


Out[101]:
$$\left ( x_{1} \vee \left(x_{2} \wedge \neg x_{3}\right) \vee \left(x_{3} \wedge \neg x_{2}\right) \vee \left(x_{3} \wedge \neg x_{4}\right), \quad \neg x_{1} \wedge \left(x_{2} \vee \neg x_{3}\right) \wedge \left(x_{3} \vee \neg x_{2}\right) \wedge \left(x_{4} \vee \neg x_{3}\right)\right )$$

In [ ]: