summaryrefslogtreecommitdiff
path: root/hdl_lab
diff options
context:
space:
mode:
Diffstat (limited to 'hdl_lab')
-rw-r--r--hdl_lab/.gitignore6
-rw-r--r--hdl_lab/Makefile13
-rw-r--r--hdl_lab/constants.py5
-rw-r--r--hdl_lab/hdl/shift_reg.py119
-rwxr-xr-xhdl_lab/myhdl.vpibin0 -> 32216 bytes
-rw-r--r--hdl_lab/myhdl_wrap.py31
6 files changed, 174 insertions, 0 deletions
diff --git a/hdl_lab/.gitignore b/hdl_lab/.gitignore
new file mode 100644
index 0000000..bae8235
--- /dev/null
+++ b/hdl_lab/.gitignore
@@ -0,0 +1,6 @@
+quartus
+gen_verilog
+simulation
+.vscode
+__pycache__
+.pytest_cache \ No newline at end of file
diff --git a/hdl_lab/Makefile b/hdl_lab/Makefile
new file mode 100644
index 0000000..c40b1cf
--- /dev/null
+++ b/hdl_lab/Makefile
@@ -0,0 +1,13 @@
+
+HDL_FOLDER = ./hdl
+HDL = $(wildcard $(HDL_FOLDER)/*.py)
+
+
+test:
+ py.test --disable-pytest-warnings -v $(HDL)
+
+test-w:
+ py.test -v $(HDL)
+
+clean:
+ $(RM) -rf simulation/* gen_verilog/* __pycache__/* .pytest_cache/* \ No newline at end of file
diff --git a/hdl_lab/constants.py b/hdl_lab/constants.py
new file mode 100644
index 0000000..d40d7c1
--- /dev/null
+++ b/hdl_lab/constants.py
@@ -0,0 +1,5 @@
+SIM_DIR = './simulation/'
+GEN_VERILOG = './gen_verilog/'
+
+IVERILOG = 'iverilog '
+VVP = 'vvp -M ./ -m myhdl ' \ No newline at end of file
diff --git a/hdl_lab/hdl/shift_reg.py b/hdl_lab/hdl/shift_reg.py
new file mode 100644
index 0000000..28914f1
--- /dev/null
+++ b/hdl_lab/hdl/shift_reg.py
@@ -0,0 +1,119 @@
+from turtle import width
+from myhdl import *
+from myhdl_wrap import Myhdl_Wrapper
+
+import random
+from random import randint
+
+random.seed(63)
+
+class ShiftReg(Myhdl_Wrapper):
+ def __init__(self):
+ super().__init__()
+
+ # Main code, this is the actual logic
+ @staticmethod
+ @block
+ def ShiftReg(reset: Signal, clk: Signal, load: Signal, in0: Signal, out0: Signal, left_right: Signal):
+
+ width = len(out0)
+
+ @instance
+ def shifter():
+ while True:
+ yield clk.posedge, reset.negedge
+
+ if not reset:
+ out0.next = load
+ else:
+ if not left_right:
+ out0.next[width:1] = out0[width-1:0]
+ out0.next[0] = in0
+ else:
+ out0.next[width-1:0] = out0[width:1]
+ out0.next[width-1] = in0
+
+ return shifter
+
+
+ @block
+ def tb(self, func):
+ reset = Signal(False)
+ clk = Signal(bool(0))
+ load = Signal(intbv(0xA5)[8:])
+ in0 = Signal(bool(0))
+ out0 = Signal(modbv(int(load))[8:])
+ left_right = Signal(bool(0))
+
+ dut = func(reset=reset, clk=clk, load=load, in0=in0, out0=out0, left_right=left_right)
+
+ @always(delay(2))
+ def clock_gen():
+ clk.next = not clk
+
+ @instance
+ def monitor():
+ last_val = out0
+
+ while True:
+ yield clk.posedge, reset.negedge
+ yield delay(1)
+
+ if reset == False:
+ assert out0 == load, "Is output is not zero at reset"
+
+ else:
+ if not left_right:
+ assert int(out0) == ((last_val << 1) & 0xFF) | int(in0), "Not shifting left correctly"
+ else:
+ assert int(out0) == ((last_val >> 1) & 0xFF) | (int(in0) << 7), "Not shifting rigth correctly"
+
+ last_val = int(out0)
+
+ @instance
+ def reset_test():
+ yield clk.negedge
+ reset.next = True
+ while True:
+ reset.next = True
+ yield delay(randint(25, 28))
+
+ reset.next = False
+ yield delay(randint(1,4))
+
+ @instance
+ def stimulus():
+ for i in range(20):
+ yield clk.negedge
+ left_right.next = 0
+ in0.next = randint(0, 1)
+
+ for i in range(20):
+ yield clk.negedge
+ left_right.next = 1
+ in0.next = randint(0, 1)
+
+ raise StopSimulation
+
+
+ return dut, clock_gen, monitor, stimulus, reset_test
+
+ def export(self):
+ reset = Signal(False)
+ clk = Signal(bool(0))
+ load = Signal(intbv(0x00)[8:])
+ in0 = Signal(bool(0))
+ out0 = Signal(modbv(int(load))[8:])
+ left_right = Signal(bool(0))
+
+ self._export(reset=reset, clk=clk, load=load, in0=in0, out0=out0, left_right=left_right)
+
+
+def test_shift_reg_sim():
+ hdl = ShiftReg()
+ hdl.sim()
+
+def test_shift_reg_cosim():
+ hdl = ShiftReg()
+ hdl.export()
+ hdl.cosim()
diff --git a/hdl_lab/myhdl.vpi b/hdl_lab/myhdl.vpi
new file mode 100755
index 0000000..1b9d393
--- /dev/null
+++ b/hdl_lab/myhdl.vpi
Binary files differ
diff --git a/hdl_lab/myhdl_wrap.py b/hdl_lab/myhdl_wrap.py
new file mode 100644
index 0000000..2e8fe4e
--- /dev/null
+++ b/hdl_lab/myhdl_wrap.py
@@ -0,0 +1,31 @@
+import os
+from myhdl import *
+from constants import *
+
+class Myhdl_Wrapper():
+ def __init__(self):
+ self.class_name = self.__class__.__name__
+
+ def _export(self, **kargs):
+ inst = getattr(self, self.class_name)(**kargs)
+ inst.convert(hdl='Verilog', path=GEN_VERILOG, name=f"{self.class_name}")
+
+
+
+ # This function links myhdl to icarus verilog sim
+ def _cosim(self, **kargs): #these should have the same signals as logic(),
+
+ iverilog_cmd = IVERILOG + f"-o {SIM_DIR}{self.class_name}.o {GEN_VERILOG}{self.class_name}.v {GEN_VERILOG}tb_{self.class_name}.v"
+ vvp_cmd = VVP + f"{SIM_DIR}{self.class_name}.o"
+
+ os.system(iverilog_cmd)
+ return Cosimulation(vvp_cmd, **kargs)
+
+ def sim(self):
+ tb = self.tb(getattr(self, self.class_name))
+ tb.config_sim(trace=True, tracebackup=False, directory=SIM_DIR, filename=f"{self.class_name}_sim")
+ tb.run_sim()
+
+ def cosim(self):
+ tb = self.tb(self._cosim)
+ tb.run_sim() \ No newline at end of file