pyarch

Hardware emulation library in python


Keywords
digital-modelling, digital-systems, hardware, vhdl
License
MIT
Install
pip install pyarch==0.0.5

Documentation

PyArch

Hardware Abstraction Library in Python

PyPI version License

  1. About PyArch
  2. Why PyArch
  3. Capabilities
  4. Installation
  5. Inbuilt Abstractions
  6. How To Use?
  7. Create your own custom abstraction
  8. To-do list
  9. Contributing
  10. License

About PyArch

PyArch is basically, a hardware abstraction library that can be used to model a digital system. It provides construct for modeling the system hierarchically and supports both top-down and bottom-up design methodologies.

Why PyArch?

As computer science students, we were reluctant to learn a totally new language (see VHDL) for hardware modelling. So, we came up with a our small-scaled version of hardware modelling in Python, a language that is pretty easy to learn!

Capabilities

  • Supports hierarchy: A digital system can be modeled as a set of interconnected components; each component, in turn, can be modeled as a set of interconnected subcomponents.

    eg: A Full Adder can be implemented using two Half Adders and one Or Gate.
    
  • Supports flexible design methodologies:

    • Top-down: A top-down approach (also known as stepwise design) is essentially the breaking down of a system to gain insight into the sub-systems that make it up. In a top-down approach an overview of the system is formulated, specifying but not detailing any first-level subsystems.
    • Bottom-up: The bottom up design model starts with most specific and basic components. It proceeds with composing higher level of components by using basic or lower level components.
    • Mixed: Both, top-down and bottom-up approaches are not practical individually. Instead, a good combination of both is recommended.
  • Structural description style: PyArch is objected oriented. Hence, it supports structural description style. Any hardware maybe emulated by specifying its sub-components using existing abstractions, or creating new ones.

  • Wide range of Abstraction levels: Ranging from abstract behavioral descriptions see Hardware to precise gate level descriptions to hardware built on top of these abstractions (Decoders, Arithmetic circuits such as Adders)

Installation

git clone https://github.com/jumpip/PyArch.git & cd PyArch/
python setup.py install

or

pip install pyarch

Inbuilt Abstractions:

  • Gates
    • AndGate
    • NandGate
    • OrGate
    • NorGate
    • XorGate
    • NotGate
  • Decoders
    • Decoder 1x2
    • Decoder 2x4
  • Arithmetic circuits
    • Half Adder
    • Full Adder
    • Parallel-in Parallel-out Adder
  • Asynchronous timing circuits
    • S-R flip flop
    • D flip flop

How to use?

See Samples

Creating a custom Hardware Abstraction

Some Basic Rules

  • Every Class/hardware extends on Hardware.
  • Every Class must be declared as New-Style not Classic-Style.
  • All the logic goes inside the hardware method of your component's Class.
  • With the help of getSignal and propagateSignal methods of Wire, read changes from input Wire instances, use your logic on them, and emit result through the output Wire instance.

Example:

class NotGate(new.Hardware,object):
        def __init__(self,x,o):
                try:
                        (len(x) != 1 or len(o) != 1)
                except NotImplementedError:
                        print('Invalid Connections')
                super(NotGate,self).__init__([x, o])
                input = []      
                input.append(x)      
                self.input = input  # A list of all the inputs   
                self.output = o   
                self.x = x
                self.o = o
                hardware = partial(hardware, self)

        def hardware(self):
                xSig = self.x[0].getSignal()
                try:
                        xSig
                except NameError:
                        self.o[0].propagateSignal(undefined)
                if(xSig == 1):
                        self.o[0].propagateSignal(0)
                else:
                        self.o[0].propagateSignal(1)

Create using already existing Abstractions

Let's create a Binary to Gray code convertor

Example:

class GrayCode_CVT(new.Hardware,object):
    def __init__(self,inp,out):
        super(GrayCode_CVT,self).__init__([inp,out])
        input=[]
        input.append(inp)   
        self.input=input
        self.output=out
        inp[0].on('signal',partial(self.hardware,inp,out))   #MSB remains same after conversion
        self.components.append(gates.XorGate([inp[0]],[inp[1]],[out[1]]))  
        self.components.append(gates.XorGate([inp[1]],[inp[2]],[out[2]]))
        self.components.append(gates.XorGate([inp[2]],[inp[3]],[out[3]]))

    def hardware(self,inp,out):
        sig = inp[0].getSignal()
        if sig:
            out[0].propagateSignal(1)
        else:
            out[0].propagateSignal(0)
Inspired from Architect

To-Do List

  • Multiplexers
  • Counters
  • Shift Registers
  • Pulse triggered FFs (JK FF, T FF)
  • Asynchronous inputs (Clear, Enable)
  • Clocked inputs

Contributing

Pick any of the topics in the task list above and get hacking! Or raise an issue or a pull request.

This repository is maintained by Jeevesh Narang, Prachi Manchanda and Mansimar Kaur

License

PyArch is distributed under the MIT License