\title{Combinational-Circuit Building Blocks aka medium scale integrated circuit (MSI) in myHDL} \author{Steven K Armour} \maketitle

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} },

@misc{peeker_simple_mux, url={http://www.xess.com/static/media/pages/peeker_simple_mux.html}, journal={Xess.com}, year={2017} },

Python Libraries Utilized


In [1]:
import numpy as np
import pandas as pd
from sympy import *
init_printing()
from myhdl import *
from myhdlpeek import *
import random
from sympy_myhdl_tools import *
pass
#https://github.com/jrjohansson/version_information
%load_ext version_information
%version_information myhdl, myhdlpeek, numpy, pandas, matplotlib, sympy, random


Out[1]:
SoftwareVersion
Python3.6.4 64bit [GCC 7.2.0]
IPython6.2.1
OSLinux 4.13.0 45 generic x86_64 with debian stretch sid
myhdl0.10
myhdlpeek0.0.6
numpy1.13.3
pandas0.21.1
matplotlib2.1.1
sympy1.1.1
randomThe 'random' distribution was not found and is required by the application
Sat Jul 07 01:20:05 2018 MDT

Multiplexers (mux)

a junction switch between one of n inputs to a single output; equivalent to a "if" or "case" statement

let $Z$ be its output $m_k$ the minterms of the controls to the mux and $I_k$ be the input feeds to the mux; then the expression for the mux in terms of boolean algebra becomes $$Z=\sum^{2^k-1}_{k=0} m_k \cdot I_k= \text{OR}(m_k \& I_k) $$

Shannon’s Expansion Theorem

The above is Shannon's theorem

it can be written more sincintly as: $$f(x_1, x_2, ..., x_n)=\bar{x_1}f(0, x_2, ..., x_n)+x_1 f(x_1, x_2, ..., x_n)$$ and then each $f(0, x_2, ..., x_n)$ \& $f(x_1, x_2, ..., x_n)$ is broken down as the above till the maximum number of control statement and minim inputs are needed


In [2]:
def shannon_exspanson(f, term):
    """
    f is not a full equation
    """
    cof0=simplify(f.subs(term, 0)); cof1=simplify(f.subs(term, 1))
    return ((~term & cof0 | (term & cof1))), cof0, cof1

2:1 MultiPlexer


In [3]:
sel, x_1in, x_2in=symbols('sel, x_1in, x_2in')

let $f(m_1, m_2, m_3)$ be the total set of minterms for a 3-bit then let $m_1$ be designated the select terms then by shannon's theorem states $$f(m_1, m_2, m_3)=\bar{m_1} \cdot f_1'(0, m_2, m_3)+m_1 \cdot f_1(1, m_2, m_3)$$ in other words we want select the two subset of the f where $m_1$ is 1 or 0 and call thouse two subsets $f_1'$, $f_1$


In [4]:
x_1in, x_2in, sel=symbols('x_1in, x_2in, sel')
$$f(m_1, m_2, m_3)$$

In [5]:
ConversionTable=pd.DataFrame()
Terms=[bin(i, 3) for i in np.arange(0, 2**3)]
ConversionTable['sel']=[int(j[0]) for j in Terms]
ConversionTable['x_1in']=[int(j[1]) for j in Terms]
ConversionTable['x_2in']=[int(j[2]) for j in Terms]
#this is shannos theorm
ConversionTable['f']=list(ConversionTable.loc[ConversionTable['sel'] == 0]['x_1in'])+list(ConversionTable.loc[ConversionTable['sel'] == 1]['x_2in'])

ConversionTable.index.name='MinMaxTerm'
ConversionTable


Out[5]:
sel x_1in x_2in f
MinMaxTerm
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

In [6]:
POS=list(ConversionTable.loc[ConversionTable['f'] == 0].index)
SOP=list(ConversionTable.loc[ConversionTable['f'] == 1].index)
f"POS: {POS}, SOP:{SOP}"


Out[6]:
'POS: [0, 1, 4, 6], SOP:[2, 3, 5, 7]'

In [7]:
f, _=POS_SOPformCalcater([sel, x_1in, x_2in], SOP, POS)
f


Out[7]:
$$\left(sel \wedge x_{2in}\right) \vee \left(x_{1in} \wedge \neg sel\right)$$

In [8]:
a, b, c=shannon_exspanson(f, sel)
f,'= via shannaon', a


Out[8]:
((sel & x_2in) | (x_1in & ~sel),
 '= via shannaon',
 (sel & x_2in) | (x_1in & ~sel))
$$\bar{m_1} \cdot f_1'(0, m_2, m_3)$$

In [9]:
m1bar_f0=~sel&x_1in; m1bar_f0


Out[9]:
$$x_{1in} \wedge \neg sel$$

In [10]:
f0Table=ConversionTable.loc[ConversionTable['sel'] == 0].copy()
f0Table['f0']=[m1bar_f0.subs({sel:i, x_1in:j}) for i, j in zip(f0Table['sel'], f0Table['x_1in'])]
f0Table


Out[10]:
sel x_1in x_2in f f0
MinMaxTerm
0 0 0 0 0 0
1 0 0 1 0 0
2 0 1 0 1 1
3 0 1 1 1 1
$$m_1 \cdot f_1(1, m_2, m_3)$$

In [11]:
m1_f1=sel&x_2in; m1_f1


Out[11]:
$$sel \wedge x_{2in}$$

In [12]:
f1Table=ConversionTable.loc[ConversionTable['sel'] == 1].copy()
f1Table['f1']=[m1_f1.subs({sel:i, x_2in:j}) for i, j in zip(f1Table['sel'], f1Table['x_2in'])]
f1Table


Out[12]:
sel x_1in x_2in f f1
MinMaxTerm
4 1 0 0 0 0
5 1 0 1 1 1
6 1 1 0 0 0
7 1 1 1 1 1

and since this is the lowest order mux this case use of shannon's theorem is kind of trivial

myHDL 2:1 MUX Gate Level and Testing


In [13]:
@block
def mux21_gates(sel, x_1in, x_2in,  f_out):
    @always_comb
    def logic():
        f_out.next=(sel and x_2in) or (x_1in and not sel)
    return logic

In [14]:
Peeker.clear()

sel, x_1in, x_2in,  f_out=[Signal(bool(0)) for _ in range(4)]
Peeker(sel, 'sel'); Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(f_out, 'f_out')

DUT=mux21_gates(sel, x_1in, x_2in,  f_out)

inputs=[sel, 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='MUX 2:1 gate type simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


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

In [16]:
Peeker.to_dataframe()


Out[16]:
f_out sel x_1in x_2in
0 0 0 0 0
1 0 0 0 1
2 1 0 1 0
3 1 0 1 1
4 0 1 0 0
5 1 1 0 1
6 0 1 1 0
7 1 1 1 1
8 1 0 1 0
9 0 1 1 0
11 1 1 0 1
12 0 1 1 0
13 0 0 0 1
14 1 1 1 1

myHDL 2:1 MUX Gate Level HDL Synthesis


In [17]:
DUT.convert()
_=VerilogTextReader('mux21_gates')


***Verilog modual from mux21_gates.v***

 // File: mux21_gates.v
// Generated by MyHDL 0.10
// Date: Sat Jul  7 01:23:00 2018


`timescale 1ns/10ps

module mux21_gates (
    sel,
    x_1in,
    x_2in,
    f_out
);


input sel;
input x_1in;
input x_2in;
output f_out;
wire f_out;





assign f_out = ((sel && x_2in) || (x_1in && (!sel)));

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL 2:1 MUX Gate level verilog code

however as will be shown doing gate implementation of MUXs is not sustainable in HDL code and this we will have to implement behavioral syntax as follows, thouse the caveat is that this only works for standard MUXs

2:1 Multiplexer Behavioral

myHDL 2:1 MUX Behavioral Level and Testing


In [18]:
@block
def mux21_behavioral(sel, x_1in, x_2in,  f_out):
    @always_comb
    def logic():
            if sel:
                f_out.next=x_1in
            else:
                f_out.next=x_2in
    return logic

In [20]:
Peeker.clear()

sel, x_1in, x_2in,  f_out=[Signal(bool(0)) for _ in range(4)]
Peeker(sel, 'sel'); Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in')
Peeker(f_out, 'f_out')

DUT=mux21_behavioral(sel, x_1in, x_2in,  f_out)

inputs=[sel, 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='MUX 2:1 behaviroal type simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


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

In [21]:
Peeker.to_dataframe()


Out[21]:
f_out sel x_1in x_2in
0 0 0 0 0
1 1 0 0 1
2 0 0 1 0
3 1 0 1 1
4 0 1 0 0
5 0 1 0 1
6 1 1 1 0
7 1 1 1 1
8 1 0 1 1
9 0 1 0 0
11 0 0 1 0
12 0 0 0 0
13 1 1 1 0
14 1 0 1 1
15 1 1 1 0

myHDL 2:1 MUX Behavioral Level HDL Synthesis


In [23]:
DUT.convert()
VerilogTextReader('mux21_behavioral');


***Verilog modual from mux21_behavioral.v***

 // File: mux21_behavioral.v
// Generated by MyHDL 0.10
// Date: Sat Jul  7 01:24:44 2018


`timescale 1ns/10ps

module mux21_behavioral (
    sel,
    x_1in,
    x_2in,
    f_out
);


input sel;
input x_1in;
input x_2in;
output f_out;
reg f_out;




always @(sel, x_1in, x_2in) begin: MUX21_BEHAVIORAL_LOGIC
    if (sel) begin
        f_out = x_1in;
    end
    else begin
        f_out = x_2in;
    end
end

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL behavioral level 2:1 MUX's verilog code

4:1 MUX

If you try to repeat the above using a 4:1 which has four input lines and needs two select lines you can become overwhelmed quickly instead it is easier to use the following diagram to than synthesis the gate level architecture

!? Insert Digram below

myHDL 4:1 MUX Gate Level and Testing


In [24]:
@block
def MUX41_gates(sel_1, sel_2, x_1in, x_2in, x_3in, x_4in,  f_out):
    @always_comb
    def logic():
        f_out.next=((not sel_1) and (not sel_2) and x_1in) or ((not sel_1) and ( sel_2) and x_2in) or (( sel_1) and (not sel_2) and x_3in) or (( sel_1) and ( sel_2) and x_4in)
    return logic

In [25]:
Peeker.clear()

sel_1, sel_2, x_1in, x_2in, x_3in, x_4in,  f_out=[Signal(bool(0)) for _ in range(7)]
Peeker(sel_1, 'sel_1'); Peeker(sel_2, 'sel_2');
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in'); Peeker(x_3in, 'x_3in'); Peeker(x_4in, 'x_4in')
Peeker(f_out, 'f_out')

DUT=MUX41_gates(sel_1, sel_2, x_1in, x_2in, x_3in, x_4in,  f_out)

inputs=[sel_1, sel_2, x_1in, x_2in, x_3in, x_4in]
sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='MUX 4:1 gate type simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


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

In [26]:
Peeker.to_dataframe()


Out[26]:
f_out sel_1 sel_2 x_1in x_2in x_3in x_4in
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 1
2 0 0 0 0 0 1 0
3 0 0 0 0 0 1 1
4 0 0 0 0 1 0 0
5 0 0 0 0 1 0 1
6 0 0 0 0 1 1 0
7 0 0 0 0 1 1 1
8 1 0 0 1 0 0 0
9 1 0 0 1 0 0 1
10 1 0 0 1 0 1 0
11 1 0 0 1 0 1 1
12 1 0 0 1 1 0 0
13 1 0 0 1 1 0 1
14 1 0 0 1 1 1 0
15 1 0 0 1 1 1 1
16 0 0 1 0 0 0 0
17 0 0 1 0 0 0 1
18 0 0 1 0 0 1 0
19 0 0 1 0 0 1 1
20 1 0 1 0 1 0 0
21 1 0 1 0 1 0 1
22 1 0 1 0 1 1 0
23 1 0 1 0 1 1 1
24 0 0 1 1 0 0 0
25 0 0 1 1 0 0 1
26 0 0 1 1 0 1 0
27 0 0 1 1 0 1 1
28 1 0 1 1 1 0 0
29 1 0 1 1 1 0 1
... ... ... ... ... ... ... ...
97 1 1 1 1 1 0 1
98 0 0 1 0 0 1 1
99 1 1 0 0 0 1 1
100 1 1 1 0 0 1 1
101 0 1 0 1 1 0 0
102 0 0 0 0 1 1 1
103 1 1 1 0 0 1 1
104 0 1 0 0 0 0 0
105 1 0 1 0 1 0 0
106 1 0 0 1 1 0 0
107 0 0 1 1 0 1 1
108 0 1 0 0 1 0 1
109 1 0 0 1 0 0 1
111 0 0 1 1 0 1 0
112 1 1 0 0 1 1 1
113 1 0 0 1 0 0 0
114 0 0 0 0 0 0 0
115 1 0 1 1 1 1 1
116 1 1 1 1 0 0 1
117 0 1 0 0 1 0 0
118 0 0 0 0 0 0 1
119 1 0 0 1 0 1 0
120 0 1 1 1 1 0 0
121 0 1 1 1 1 1 0
122 1 1 1 0 0 1 1
123 1 0 1 1 1 1 0
124 1 1 0 0 0 1 0
125 1 1 1 0 0 1 1
126 0 1 1 0 1 0 0
127 0 0 1 1 0 0 1

123 rows × 7 columns

myHDL 4:1 MUX Gate Level HDL Synthesis


In [27]:
DUT.convert()
VerilogTextReader('MUX41_gates');


***Verilog modual from MUX41_gates.v***

 // File: MUX41_gates.v
// Generated by MyHDL 0.10
// Date: Sat Jul  7 01:25:39 2018


`timescale 1ns/10ps

module MUX41_gates (
    sel_1,
    sel_2,
    x_1in,
    x_2in,
    x_3in,
    x_4in,
    f_out
);


input sel_1;
input sel_2;
input x_1in;
input x_2in;
input x_3in;
input x_4in;
output f_out;
wire f_out;





assign f_out = (((!sel_1) && (!sel_2) && x_1in) || ((!sel_1) && sel_2 && x_2in) || (sel_1 && (!sel_2) && x_3in) || (sel_1 && sel_2 && x_4in));

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL 4:1 MUX Gate level verilog code

4:1 Multiplexer Behavioral

As one can clearly see this is not sustainable and thus 'if' Statements need to be used via behavioral logic modeling

myHDL 4:1 MUX Behavioral Level and Testing


In [28]:
@block
def MUX41_behavioral(sel_1, sel_2, x_1in, x_2in, x_3in, x_4in,  f_out):
    @always_comb
    def logic():
        if (not sel_1) and (not sel_2):
            f_out.next=x_1in
        
        elif (not sel_1) and sel_2:
            f_out.next=x_2in
        
        elif sel_1 and (not sel_2):
            f_out.next=x_3in
        
        else:
            f_out.next=x_4in
    
    return logic

In [29]:
Peeker.clear()

sel_1, sel_2, x_1in, x_2in, x_3in, x_4in,  f_out=[Signal(bool(0)) for _ in range(7)]
Peeker(sel_1, 'sel_1'); Peeker(sel_2, 'sel_2');
Peeker(x_1in, 'x_1in'); Peeker(x_2in, 'x_2in'); Peeker(x_3in, 'x_3in'); Peeker(x_4in, 'x_4in')
Peeker(f_out, 'f_out')

DUT=MUX41_behavioral(sel_1, sel_2, x_1in, x_2in, x_3in, x_4in,  f_out)

inputs=[sel_1, sel_2, x_1in, x_2in, x_3in, x_4in]
sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='MUX 4:1 behavioral type simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


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

In [30]:
Peeker.to_dataframe()


Out[30]:
f_out sel_1 sel_2 x_1in x_2in x_3in x_4in
0 0 0 0 0 0 0 0
1 0 0 0 0 0 0 1
2 0 0 0 0 0 1 0
3 0 0 0 0 0 1 1
4 0 0 0 0 1 0 0
5 0 0 0 0 1 0 1
6 0 0 0 0 1 1 0
7 0 0 0 0 1 1 1
8 1 0 0 1 0 0 0
9 1 0 0 1 0 0 1
10 1 0 0 1 0 1 0
11 1 0 0 1 0 1 1
12 1 0 0 1 1 0 0
13 1 0 0 1 1 0 1
14 1 0 0 1 1 1 0
15 1 0 0 1 1 1 1
16 0 0 1 0 0 0 0
17 0 0 1 0 0 0 1
18 0 0 1 0 0 1 0
19 0 0 1 0 0 1 1
20 1 0 1 0 1 0 0
21 1 0 1 0 1 0 1
22 1 0 1 0 1 1 0
23 1 0 1 0 1 1 1
24 0 0 1 1 0 0 0
25 0 0 1 1 0 0 1
26 0 0 1 1 0 1 0
27 0 0 1 1 0 1 1
28 1 0 1 1 1 0 0
29 1 0 1 1 1 0 1
... ... ... ... ... ... ... ...
97 0 0 0 0 0 1 0
98 0 0 1 1 0 1 1
99 0 1 0 0 0 0 1
100 1 1 1 0 0 1 1
101 1 1 0 0 1 1 1
102 0 1 0 1 0 0 0
103 1 1 0 1 1 1 1
104 0 1 0 1 0 0 0
105 1 1 1 1 0 0 1
106 0 0 1 1 0 1 1
107 1 0 0 1 0 1 0
108 1 0 1 1 1 1 1
109 0 0 1 0 0 1 0
110 0 0 0 0 1 0 0
111 1 1 1 1 0 1 1
113 0 1 1 1 0 1 0
114 1 1 0 1 1 1 1
115 0 1 0 0 0 0 1
116 1 0 1 0 1 0 1
117 0 0 0 0 1 1 1
118 0 1 1 0 1 0 0
119 1 1 0 0 0 1 0
120 1 0 1 0 1 0 0
121 1 0 0 1 1 1 1
122 1 1 1 1 1 1 1
123 0 1 0 0 0 0 1
124 0 1 0 1 1 0 1
125 1 1 1 1 0 1 1
126 0 1 0 1 1 0 1
127 0 0 0 0 0 0 0

126 rows × 7 columns

myHDL 4:1 MUX Behavioral Level HDL Synthesis


In [31]:
DUT.convert()
VerilogTextReader('MUX41_behavioral');


***Verilog modual from MUX41_behavioral.v***

 // File: MUX41_behavioral.v
// Generated by MyHDL 0.10
// Date: Sat Jul  7 01:26:38 2018


`timescale 1ns/10ps

module MUX41_behavioral (
    sel_1,
    sel_2,
    x_1in,
    x_2in,
    x_3in,
    x_4in,
    f_out
);


input sel_1;
input sel_2;
input x_1in;
input x_2in;
input x_3in;
input x_4in;
output f_out;
reg f_out;




always @(sel_2, x_1in, sel_1, x_3in, x_4in, x_2in) begin: MUX41_BEHAVIORAL_LOGIC
    if (((!sel_1) && (!sel_2))) begin
        f_out = x_1in;
    end
    else if (((!sel_1) && sel_2)) begin
        f_out = x_2in;
    end
    else if ((sel_1 && (!sel_2))) begin
        f_out = x_3in;
    end
    else begin
        f_out = x_4in;
    end
end

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL behavioral level 4:1 MUX's verilog code

4:1 Multiplexer Behavioral with bitvectors

taking this a step further using bytes we can implement the behavioral using vector inputs instead of single bit inputs as follows

How bit vectors work in myHDL and in Verilog/VHDL

Understanding BitVector bit selection in myHDL


In [32]:
sel=intbv(1)[2:]; x_in=intbv(7)[4:]; f_out=bool(0)

In [33]:
for i in x_in:
    print(i)


False
True
True
True

In [34]:
for i in range(4):
    print(x_in[i])


True
True
True
False

myHDL 4:1 MUX Behavioral with BitVecters and Testing

!? This needs to be checked


In [35]:
@block
def MUX41_behavioralVec(sel, x_in, f_out):
    @always_comb
    def logic():
        f_out.next=x_in[sel]
    return logic

In [36]:
Peeker.clear()
sel=Signal(intbv(0)[2:]); Peeker(sel, 'sel')
x_in=Signal(intbv(0)[4:]); Peeker(x_in, 'x_in')
f_out=Signal(bool(0)); Peeker(f_out, 'f_out')

DUT=MUX41_behavioralVec(sel, x_in, f_out)

def MUX41_behavioralVec_TB(sel, x_in):
    
    selLen=len(sel); x_inLen=len(x_in)
    
    for i in range(2**x_inLen):
        x_in.next=i
        for j in range(selLen):
            sel.next=j
            
            yield delay(1)
            now()

In [37]:
im=Simulation(DUT, MUX41_behavioralVec_TB(sel, x_in), *Peeker.instances()).run()        
Peeker.to_wavedrom(tock=True,
                  title='MUX 4:1 behavioral vectype simulation')


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

In [38]:
Peeker.to_dataframe()


Out[38]:
f_out sel x_in
0 0 0 0
1 0 1 0
2 1 0 1
3 0 1 1
4 0 0 2
5 1 1 2
6 1 0 3
7 1 1 3
8 0 0 4
9 0 1 4
10 1 0 5
11 0 1 5
12 0 0 6
13 1 1 6
14 1 0 7
15 1 1 7
16 0 0 8
17 0 1 8
18 1 0 9
19 0 1 9
20 0 0 10
21 1 1 10
22 1 0 11
23 1 1 11
24 0 0 12
25 0 1 12
26 1 0 13
27 0 1 13
28 0 0 14
29 1 1 14
30 1 0 15
31 1 1 15

myHDL 4:1 MUX Behavioral with BitVecters HDL Synthesis


In [39]:
DUT.convert()
VerilogTextReader('MUX41_behavioralVec');


***Verilog modual from MUX41_behavioralVec.v***

 // File: MUX41_behavioralVec.v
// Generated by MyHDL 0.10
// Date: Sat Jul  7 01:27:41 2018


`timescale 1ns/10ps

module MUX41_behavioralVec (
    sel,
    x_in,
    f_out
);


input [1:0] sel;
input [3:0] x_in;
output f_out;
wire f_out;





assign f_out = x_in[sel];

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL behavioral level 4:1 MUX using Bitvecters verilog code

Generic Expressions via MUXs

(clean this and find harder exsample)

while shannon's theorem did not prove very much useful in designing a 4:1 MUX it's true power lies converting boolean logic expression from and or gates to MUX's

using example 4.5 from Brown & Vranesic 3rd Ed


In [40]:
w1, w2, w3=symbols('w_1, w_2, w_3')
f=(~w1&~w3)|(w1&w2)|(w1&w3)
f


Out[40]:
$$\left(w_{1} \wedge w_{2}\right) \vee \left(w_{1} \wedge w_{3}\right) \vee \left(\neg w_{1} \wedge \neg w_{3}\right)$$

In [41]:
s1=w1
fp, fp0, fp1=shannon_exspanson(f, s1)
fp, fp0, fp1


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

In [42]:
s2=w2
fpp0, fpp00, fpp01=shannon_exspanson(fp0, s2)
fpp1, fpp10, fpp11=shannon_exspanson(fp1, s2)

fpp0, fpp00, fpp01, fpp1, fpp10, fpp11


Out[42]:
$$\left ( \left(w_{2} \wedge \neg w_{3}\right) \vee \left(\neg w_{2} \wedge \neg w_{3}\right), \quad \neg w_{3}, \quad \neg w_{3}, \quad w_{2} \vee \left(w_{3} \wedge \neg w_{2}\right), \quad w_{3}, \quad \mathrm{True}\right )$$

myHDL Generic Expression via MUXs and Testing


In [43]:
@block
def Shannon21MUX(s1, s2, w_3in, f_out):
    @always_comb
    def logic():
        if (not s1) and (not s2):
            f_out.next=not w_3in
        elif (not s1) and ( s2):
            f_out.next=not w_3in
        elif ( s1) and (not s2):
            f_out.next= w_3in
        else:
            f_out.next=1
    return logic

In [44]:
Peeker.clear()

s1, s2, w_3in,  f_out=[Signal(bool(0)) for _ in range(4)]
Peeker(s1, 's1'); Peeker(s2, 's2');
Peeker(w_3in, 'w_3in')
Peeker(f_out, 'f_out')

DUT=Shannon21MUX(s1, s2, w_3in, f_out)

inputs=[s1, s2, w_3in, f_out]
sim=Simulation(DUT, Combo_TB(inputs), *Peeker.instances()).run()        
Peeker.to_wavedrom(start_time=0, stop_time=2*2**len(inputs), tock=True,
                  title='Shannon 2:1 MUX gate type simulation',
                  caption=f'after clock cycle {2**len(inputs)-1} ->random input')


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

In [45]:
Peeker.to_dataframe()


Out[45]:
f_out s1 s2 w_3in
0 1 0 0 0
2 0 0 0 1
3 1 0 0 1
4 1 0 1 0
6 0 0 1 1
7 1 0 1 1
8 0 1 0 0
9 1 1 0 0
10 1 1 0 1
12 1 1 1 0
14 1 1 1 1
16 0 0 1 1
17 1 1 0 1
18 1 0 1 0
19 1 1 0 1
20 0 0 0 1
21 0 1 0 0
22 0 0 0 1
23 1 0 0 1
24 1 0 1 0
25 1 1 0 1
26 1 0 0 0
27 1 1 1 0
28 1 0 1 0
29 0 0 1 1
30 1 0 0 0

myHDL Generic Expression via MUXs HDL Synthesis


In [46]:
DUT.convert()
VerilogTextReader('Shannon21MUX');


***Verilog modual from Shannon21MUX.v***

 // File: Shannon21MUX.v
// Generated by MyHDL 0.10
// Date: Sat Jul  7 01:28:46 2018


`timescale 1ns/10ps

module Shannon21MUX (
    s1,
    s2,
    w_3in,
    f_out
);


input s1;
input s2;
input w_3in;
output f_out;
reg f_out;




always @(s2, w_3in, s1) begin: SHANNON21MUX_LOGIC
    if (((!s1) && (!s2))) begin
        f_out = (!w_3in);
    end
    else if (((!s1) && s2)) begin
        f_out = (!w_3in);
    end
    else if ((s1 && (!s2))) begin
        f_out = w_3in;
    end
    else begin
        f_out = 1;
    end
end

endmodule

The following shows the Xilinx's Vivado 2016.1 RTL generated schematic of our myHDL 2:1 Mux expansion of $f$ using Shannon's Expansion Theorom

Demultiplexers

Encoders

Decoders