From 987134966d0c3ab9b1a5775c8f01fa707408780b Mon Sep 17 00:00:00 2001 From: jjsuperpower Date: Sun, 26 Jun 2022 09:40:18 -0500 Subject: restructured folder --- hdl_lab/.gitignore | 6 +++ hdl_lab/Makefile | 13 ++++++ hdl_lab/constants.py | 5 ++ hdl_lab/hdl/shift_reg.py | 119 +++++++++++++++++++++++++++++++++++++++++++++++ hdl_lab/myhdl.vpi | Bin 0 -> 32216 bytes hdl_lab/myhdl_wrap.py | 31 ++++++++++++ 6 files changed, 174 insertions(+) create mode 100644 hdl_lab/.gitignore create mode 100644 hdl_lab/Makefile create mode 100644 hdl_lab/constants.py create mode 100644 hdl_lab/hdl/shift_reg.py create mode 100755 hdl_lab/myhdl.vpi create mode 100644 hdl_lab/myhdl_wrap.py (limited to 'hdl_lab') 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 Binary files /dev/null and b/hdl_lab/myhdl.vpi 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 -- cgit v1.2.3