mirror of
https://github.com/ehw-fit/ariths-gen.git
synced 2025-04-08 00:02:12 +01:00
Merge pull request #17 from ehw-fit/devel
This commit is contained in:
commit
2d7e157453
27
.github/workflows/generate.yml
vendored
27
.github/workflows/generate.yml
vendored
@ -17,9 +17,9 @@ jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
# Semantic version range syntax or exact version of a Python version
|
||||
python-version: '3.x'
|
||||
@ -44,14 +44,17 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
needs: build
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install iverilog
|
||||
run: sudo apt install iverilog
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
# Semantic version range syntax or exact version of a Python version
|
||||
python-version: '3.x'
|
||||
- run: python -m pip install numpy
|
||||
- name: Download workflow run artifacts
|
||||
uses: actions/download-artifact@v2
|
||||
uses: actions/download-artifact@v3
|
||||
with:
|
||||
name: arithmetic-circuits-8
|
||||
path: test_circuits
|
||||
@ -84,12 +87,12 @@ jobs:
|
||||
needs: build
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: [ '3.6.x', '3.7.x', '3.8.x', '3.9.x', '3.10.0-rc.2' ]
|
||||
python-version: [ '3.7', '3.8', '3.9', '3.10', '3.11' ]
|
||||
name: Python ${{ matrix.python-version }} test
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Setup python
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
architecture: x64
|
||||
@ -104,9 +107,9 @@ jobs:
|
||||
needs: test
|
||||
if: github.ref == 'refs/heads/main'
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/checkout@v3
|
||||
- name: Set up Python 3.x
|
||||
uses: actions/setup-python@v2
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
# Semantic version range syntax or exact version of a Python version
|
||||
python-version: '3.x'
|
||||
@ -120,12 +123,12 @@ jobs:
|
||||
- name: Generate documentation
|
||||
run: pdoc --html ariths_gen
|
||||
- name: Upload results
|
||||
uses: actions/upload-artifact@v1.0.0
|
||||
uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: documentation
|
||||
path: html
|
||||
- name: Deploy 🚀
|
||||
uses: JamesIves/github-pages-deploy-action@4.1.4
|
||||
uses: JamesIves/github-pages-deploy-action@4
|
||||
with:
|
||||
branch: gh-pages # The branch the action should deploy to.
|
||||
folder: html/ariths_gen # The folder the action should deploy.
|
@ -46,6 +46,11 @@ class GeneralCircuit():
|
||||
|
||||
return self.pyc(*args)
|
||||
|
||||
def __str__(self):
|
||||
return f"<{type(self).__name__} prefix={self.prefix} " + (", ".join([f"input={i}" for i in self.inputs])) + ">"
|
||||
|
||||
#super().__init__(prefix, name, out_N, inner_component, inputs=[a, b], signed=signed, **kwargs)
|
||||
|
||||
def add_component(self, component):
|
||||
"""Adds a component into list of circuit's inner subcomponents.
|
||||
|
||||
|
@ -76,6 +76,12 @@ class Bus():
|
||||
Wire: Returning wire from the bus.
|
||||
"""
|
||||
return self.bus[wire_index]
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.bus[i]
|
||||
|
||||
def __getitem__(self, i):
|
||||
return self.get_wire(i)
|
||||
|
||||
# Connecting output wire of the inner circuit component to desired position in the described circuit's output bus
|
||||
def connect(self, bus_wire_index: int, inner_component_out_wire: Wire, inserted_wire_desired_index: int = -1):
|
||||
@ -100,6 +106,9 @@ class Bus():
|
||||
elif inserted_wire_desired_index != -1:
|
||||
self.bus[bus_wire_index] = Wire(name=inner_component_out_wire.name, prefix=inner_component_out_wire.parent_bus.prefix, index=inserted_wire_index, value=inner_component_out_wire.value, parent_bus=self)
|
||||
|
||||
def __setitem__(self, i, v):
|
||||
self.connect(i, v)
|
||||
|
||||
def connect_bus(self, connecting_bus: object, start_connection_pos: int = 0, end_connection_pos: int = -1, offset: int = 0):
|
||||
"""Ensures connection of specified bus wires to this bus wires.
|
||||
|
||||
@ -127,7 +136,7 @@ class Bus():
|
||||
# Ensures correct binding between the bus wire index and the wire itself
|
||||
# It is used for the case when multiple of the same wire (e.g. `ContantWireValue0()`) are present in the bus (its id would otherwise be incorrect when using `self.bus.index(_)`)
|
||||
mapped_positions = [(w_id, self.bus[w_id]) for w_id in range(self.N)]
|
||||
return "".join([f" {self.prefix} = 0\n"] + [f" {self.prefix} |= {w[1].return_wire_value_python_flat(offset=w[0])}" for w in mapped_positions])
|
||||
return "".join([f" {self.prefix} = 0\n"] + [f" {self.prefix} = ({self.prefix}) | {w[1].return_wire_value_python_flat(offset=w[0])}" for w in mapped_positions])
|
||||
|
||||
def return_bus_wires_sign_extend_python_flat(self):
|
||||
"""Sign extends the bus's corresponding Python variable (object) to ensure proper flat Python code variable signedness.
|
||||
@ -137,10 +146,13 @@ class Bus():
|
||||
"""
|
||||
if self.signed is True:
|
||||
last_bus_wire = self.bus[-1]
|
||||
return "".join([f" {self.prefix} |= {last_bus_wire.return_wire_value_python_flat(offset=i)}" for i in range(len(self.bus), 64)])
|
||||
return "".join([f" {self.prefix} = ({self.prefix}) | {last_bus_wire.return_wire_value_python_flat(offset=i)}" for i in range(len(self.bus), 64)])
|
||||
else:
|
||||
return ""
|
||||
|
||||
def __str__(self):
|
||||
return f"<wire N={self.N} prefix={self.prefix} \"" + (",".join([str(w) for w in self.bus])) + "\">"
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_declaration_c(self):
|
||||
"""Bus declaration in C code.
|
||||
|
@ -40,13 +40,14 @@ class Wire():
|
||||
str: Python code bitwise shift for storing (constant/variable) wire value at desired offset position.
|
||||
"""
|
||||
if self.is_const():
|
||||
return f"({self.c_const}) << {offset}\n"
|
||||
return f"(({self.c_const}) << {offset})\n"
|
||||
# If wire is part of an input bus (where wire names are concatenated from bus prefix and their index position inside the bus in square brackets)
|
||||
# then the wire value is obtained from bitwise shifting the required wire from the parent bus ('parent_bus.prefix' is the same value as 'self.prefix')
|
||||
elif self.is_buswire():
|
||||
return f"(({self.prefix} >> {self.index}) & 0x01) << {offset}\n"
|
||||
return f"((({self.prefix} >> {self.index}) & 0x01) << {offset})\n"
|
||||
|
||||
else:
|
||||
return f"(({self.name} >> 0) & 0x01) << {offset}\n"
|
||||
return f"((({self.name} >> 0) & 0x01) << {offset})\n"
|
||||
|
||||
""" C CODE GENERATION """
|
||||
def get_declaration_c(self):
|
||||
@ -246,6 +247,13 @@ class Wire():
|
||||
else:
|
||||
return self.prefix
|
||||
|
||||
def __str__(self):
|
||||
if self.is_const():
|
||||
return f"<w={self.c_const}>"
|
||||
elif self.is_buswire():
|
||||
return f"<w={self.prefix}[{self.index}]>"
|
||||
else:
|
||||
return f"<w={self.name}>"
|
||||
|
||||
# Wires with constant values #
|
||||
class ConstantWireValue0(Wire):
|
||||
@ -281,6 +289,7 @@ class ConstantWireValue0(Wire):
|
||||
return True
|
||||
|
||||
|
||||
|
||||
class ConstantWireValue1(Wire):
|
||||
"""Class representing wire carrying constant value 1 used to interconnect components.
|
||||
|
||||
@ -312,3 +321,4 @@ class ConstantWireValue1(Wire):
|
||||
bool: True, because constant wire carries a constant value 1.
|
||||
"""
|
||||
return True
|
||||
|
||||
|
@ -35,6 +35,16 @@ from ariths_gen.multi_bit_circuits.approximate_multipliers import (
|
||||
UnsignedBrokenArrayMultiplier,
|
||||
UnsignedBrokenCarrySaveMultiplier
|
||||
)
|
||||
|
||||
from ariths_gen.one_bit_circuits.logic_gates import (
|
||||
AndGate,
|
||||
NandGate,
|
||||
OrGate,
|
||||
NorGate,
|
||||
XorGate,
|
||||
XnorGate,
|
||||
NotGate
|
||||
)
|
||||
import numpy as np
|
||||
|
||||
|
||||
@ -163,4 +173,33 @@ def test_mac():
|
||||
|
||||
r = mymac(av, bv, cv)
|
||||
expected = (av * bv) + cv
|
||||
np.testing.assert_array_equal(r, expected)
|
||||
np.testing.assert_array_equal(r, expected)
|
||||
|
||||
def test_direct():
|
||||
class err_circuit(GeneralCircuit):
|
||||
def __init__(self, prefix: str = "", name: str = "adder", inner_component: bool = True, a: Bus = Bus(), b: Bus = Bus()):
|
||||
super().__init__(prefix = prefix, name=name, out_N = (a.N + 1), inner_component=inner_component, inputs = [a, b])
|
||||
self.N = 1
|
||||
self.prefix = prefix
|
||||
self.a = Bus(prefix=a.prefix, wires_list=a.bus)
|
||||
self.b = Bus(prefix=b.prefix, wires_list=b.bus)
|
||||
self.out = Bus(self.prefix+"_out", self.N+1)
|
||||
|
||||
a_0 = self.a[0]
|
||||
b_0 = self.b.get_wire(0)
|
||||
|
||||
or_1 = OrGate(a_0, b_0, prefix=self.prefix+"_or"+str(self.get_instance_num(cls=OrGate)), parent_component=self)
|
||||
self.add_component(or_1)
|
||||
|
||||
self.out.connect(0, a_0)
|
||||
self.out.connect(1, or_1.out)
|
||||
|
||||
|
||||
av = np.arange(0, 4).reshape(1, -1)
|
||||
bv = np.arange(0, 4).reshape(-1, 1)
|
||||
example = err_circuit(prefix = "err_circuit", a = Bus("a", 2) , b = Bus("b", 2))
|
||||
|
||||
r = example(av, bv)
|
||||
expected = np.array([[0, 3, 0, 3], [2, 3 ,2, 3], [0, 3, 0, 3], [2, 3, 2, 3]])
|
||||
np.testing.assert_equal(r, expected)
|
||||
print(r)
|
Loading…
x
Reference in New Issue
Block a user