From 43fb4beb6ed74a2a5dbdb13b1f89e44212570b2c Mon Sep 17 00:00:00 2001 From: Dennis Brentjes Date: Sun, 9 Jan 2022 22:42:14 +0100 Subject: [PATCH] Makes a seperate component that handles the ExiClk --- re-bba/{Counter/counter.py => Counter.py} | 0 re-bba/ExiClock.py | 115 ++++++++++++++++++++ re-bba/{LedBlinker => }/LedBlinker.py | 0 re-bba/{ShiftRegister => }/ShiftRegister.py | 46 ++------ re-bba/re-bba.py | 12 +- 5 files changed, 133 insertions(+), 40 deletions(-) rename re-bba/{Counter/counter.py => Counter.py} (100%) create mode 100644 re-bba/ExiClock.py rename re-bba/{LedBlinker => }/LedBlinker.py (100%) rename re-bba/{ShiftRegister => }/ShiftRegister.py (74%) diff --git a/re-bba/Counter/counter.py b/re-bba/Counter.py similarity index 100% rename from re-bba/Counter/counter.py rename to re-bba/Counter.py diff --git a/re-bba/ExiClock.py b/re-bba/ExiClock.py new file mode 100644 index 0000000..7228772 --- /dev/null +++ b/re-bba/ExiClock.py @@ -0,0 +1,115 @@ + +import enum +import sys +import os + +from amaranth.build import Platform +from amaranth import * +from amaranth.sim import Simulator + +class ClockState(enum.Enum): + LOW = 0 + FALLING = 1 + HIGH = 2 + RISING = 3 + +class ExiClock(Elaboratable): + + def __init__(self): + # Ports + self.exiClk = Signal() + self.exiClkState = Signal(2) + + # State + self.prevExiClkValid = Signal() + self.prevExiClk = Signal() + self.prevExiClkState = Signal(2) + + + def elaborate(self, platform: Platform): + m = Module() + + with m.If(self.prevExiClkValid): + with m.If(self.prevExiClkState == ClockState.FALLING): + m.d.sync += self.exiClkState.eq(ClockState.LOW) + with m.Elif(self.prevExiClkState == ClockState.RISING): + m.d.sync += self.exiClkState.eq(ClockState.HIGH) + with m.Else(): + with m.If(self.prevExiClk ^ self.exiClk): + m.d.sync += self.exiClkState.eq(Cat(1, self.exiClk)) + with m.Else(): + m.d.sync += self.exiClkState.eq(Cat(0, self.exiClk)) + + m.d.sync += self.prevExiClkState.eq(self.exiClkState) + + m.d.sync += self.prevExiClk.eq(self.exiClk) + m.d.sync += self.prevExiClkValid.eq(1) + + return m + +##### +# TestBench +##### +class TestBench: + def __init__(self): + pass + + def FlipExiClock(self, dut): + yield dut.exiClk.eq(~dut.exiClk) + + def clockTest(self): + dut = self.dut + + yield dut.exiClk.eq(0) + yield + yield from self.FlipExiClock(dut) + yield + yield + assert (yield dut.exiClkState) == ClockState.RISING.value + yield + yield + assert (yield dut.exiClkState) == ClockState.HIGH.value + yield + yield + yield from self.FlipExiClock(dut) + yield + yield + assert (yield dut.exiClkState) == ClockState.FALLING.value + yield + yield + assert (yield dut.exiClkState) == ClockState.LOW.value + yield + + + def simulate(self): + self.dut = ExiClock() + + sim = Simulator(self.dut) + sim.add_clock(1e-6) # 1 MHz + sim.add_sync_process(self.clockTest) + + with sim.write_vcd(os.path.dirname(os.path.abspath(__file__)) + "/ExiClock.vcd"): + sim.run() + +##### +# Main portion +##### + +def main(): + if(len(sys.argv) == 2): + + if sys.argv[1] == "s": + bench = TestBench() + bench.simulate() + + if sys.argv[1] == "v": + mod = ExiClock() + with open(os.path.dirname(os.path.abspath(__file__)) + "/ExiClock.v", "w") as f: + f.write(verilog.convert(mod, ports=[mod.exiClk, mod.exiClkState])) + + else: + bench = TestBench() + bench.simulate() + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/re-bba/LedBlinker/LedBlinker.py b/re-bba/LedBlinker.py similarity index 100% rename from re-bba/LedBlinker/LedBlinker.py rename to re-bba/LedBlinker.py diff --git a/re-bba/ShiftRegister/ShiftRegister.py b/re-bba/ShiftRegister.py similarity index 74% rename from re-bba/ShiftRegister/ShiftRegister.py rename to re-bba/ShiftRegister.py index 75fef7b..2136803 100644 --- a/re-bba/ShiftRegister/ShiftRegister.py +++ b/re-bba/ShiftRegister.py @@ -1,61 +1,36 @@ -import enum -import sys import os from amaranth import * +from amaranth.build import Platform from amaranth.back import verilog from amaranth.sim import Simulator +from ExiClock import ClockState ##### # Hardware Description. ##### -class ClockState(enum.Enum): - LOW = 0 - FALLING = 1 - HIGH = 2 - RISING = 3 - class ShiftRegister(Elaboratable): def __init__(self, width): self.width = width # Ports self.nen = Signal() + self.exiClkState = Signal(2) self.rst = Signal() - self.inb = Signal() - self.exiClk = Signal() self.data = Signal(self.width, reset=0) - # State - self.prevExiClkValid = Signal() - self.prevExiClk = Signal() - self.prevExiClkState = Signal(2) - self.exiClkState = Signal(2) - - def elaborate(self, platform): + def elaborate(self, platform: Platform): m = Module() with m.If(self.rst): m.d.sync += self.data.eq(self.data.reset) with m.If(~self.nen): - with m.If(self.prevExiClkValid): - m.d.sync += self.prevExiClkState.eq(self.exiClkState) - with m.If(self.prevExiClk ^ self.exiClk): - m.d.sync += self.exiClkState.eq(Cat(self.exiClk, 1)) - with m.Else(): - m.d.sync += self.exiClkState.eq(Cat(self.exiClk, 0)) + with m.If(self.exiClkState == ClockState.FALLING): + m.d.sync += self.data.eq(self.data.shift_left(1) | self.inb ) - with m.If((self.exiClkState == ClockState.FALLING).bool() & (self.exiClkState != self.prevExiClkState).bool()): - m.d.sync += self.data.eq(self.data.shift_left(1) | self.inb ) - - m.d.sync += self.prevExiClkValid.eq(1) - m.d.sync += self.prevExiClk.eq(self.exiClk) - with m.Else(): - m.d.sync += self.prevExiClkValid.eq(0) - return m ##### @@ -133,6 +108,10 @@ class TestBench: with sim.write_vcd(os.path.dirname(os.path.abspath(__file__)) + "/ShiftRegister_shift.vcd"): sim.run() +##### +# Main portion +##### + def main(): if(len(sys.argv) == 2): @@ -149,11 +128,6 @@ def main(): bench = TestBench() bench.simulate() - -##### -# Main portion -##### - if __name__ == "__main__": main() diff --git a/re-bba/re-bba.py b/re-bba/re-bba.py index fdb452b..dc7f5b1 100644 --- a/re-bba/re-bba.py +++ b/re-bba/re-bba.py @@ -4,9 +4,10 @@ from amaranth import * from amaranth.back import verilog from amaranth.build.plat import Platform from amaranth.sim import Simulator -from amaranth_boards.icebreaker import *; +from amaranth_boards.icebreaker import * -from ShiftRegister.ShiftRegister import *; +from ExiClock import ExiClock +from ShiftRegister import ShiftRegister class ReBba(Elaboratable): def __init__(self): @@ -25,6 +26,8 @@ class ReBba(Elaboratable): btn2 = platform.request("button", 2) btn3 = platform.request("button", 3) + exiClk = ExiClock() + m.submodules += exiClk sr = ShiftRegister(5) m.submodules += sr @@ -34,11 +37,12 @@ class ReBba(Elaboratable): m.d.comb += led4.eq(sr.data[3]) m.d.comb += led5.eq(sr.data[4]) - m.d.comb += sr.exiClk.eq(btn3) + m.d.comb += exiClk.exiClk.eq(btn3) + m.d.comb += sr.rst.eq(btn2) m.d.comb += sr.inb.eq(btn1) - m.d.comb += sr.nen.eq(Const(0)) + m.d.comb += sr.exiClkState.eq(exiClk.exiClkState) return m