In the previous lesson we have seen how to implement a 1 bit full adder using structural design. In this lesson we will see how to implement it behaviouraly
import sys
import platform
if (platform.uname().node == 'TPY14'):
print('Dev machine')
sys.path.append('..\\..\\..\\py4hw')
Dev machine
import py4hw
class FullAdder(py4hw.Logic):
def __init__(self, parent, name, x, y, ci, s, co):
super().__init__(parent, name)
self.x = self.addIn('x', x)
self.y = self.addIn('y', y)
self.ci = self.addIn('ci', ci)
self.s = self.addOut('s', s)
self.co = self.addOut('co', co)
def propagate(self):
self.s.put((self.x.get() ^ self.y.get()) ^ self.ci.get())
self.co.put((self.x.get() & self.y.get()) | ( (self.x.get() ^ self.y.get()) & self.ci.get()))
In this case the circuit has no schematic to provide, then it will raise an exception if you try to draw it
sys = py4hw.HWSystem()
x = sys.wire('x')
y = sys.wire('y')
ci = sys.wire('ci')
s = sys.wire('s')
co = sys.wire('co')
fa = FullAdder(sys, 'fa', x, y, ci, s, co)
sch = py4hw.Schematic(fa)
sch.draw()
--------------------------------------------------------------------------- Exception Traceback (most recent call last) ~\AppData\Local\Temp\ipykernel_17236\1901126793.py in <module> ----> 1 sch = py4hw.Schematic(fa) 2 sch.draw() C:\Projects\Research\INT_Py4hw\py4hw\py4hw\schematic.py in __init__(self, obj, render, parent, placeAndRoute) 247 248 if not(obj.isStructural()): --> 249 raise Exception('Schematics are only available to structural circuits') 250 251 self.sys = obj Exception: Schematics are only available to structural circuits
However, you can simulate it. If you have a look at previous results you will see that the behaviour is equivalent.
sys = py4hw.HWSystem()
x = sys.wire('x')
y = sys.wire('y')
ci = sys.wire('ci')
s = sys.wire('s')
co = sys.wire('co')
py4hw.Sequence(sys, 'ci', [0,1], ci)
py4hw.Sequence(sys, 'y', [0,0,1,1], y)
py4hw.Sequence(sys, 'x', [0,0,0,0,1,1,1,1], x)
fa = FullAdder(sys, 'fa', x, y, ci, s, co)
wf = py4hw.Waveform(sys, 'wf', [x, y, ci, s, co])
sys.getSimulator().clk(20)
wf.draw_wavedrom(shortNames=True)
What about synthesis?
rtlgen = py4hw.VerilogGenerator(fa)
print(rtlgen.getVerilog(noInstanceNumber=True))
transpiling /HWSystem[HWSystem]/FullAdder[fa] // This file was automatically created by py4hw RTL generator module FullAdder ( input x, input y, input ci, output reg s, output reg co); // Code generated from propagate method // variable declaration reg i0; reg i1; reg i2; reg i3; // process always @(*) begin s<=i0^ci; co<=i1|i2; i0<=x^y; i1<=x&y; i2<=i3&ci; i3<=x^y; end endmodule