Makes a seperate component that handles the ExiClk
This commit is contained in:
parent
f7106abe87
commit
43fb4beb6e
115
re-bba/ExiClock.py
Normal file
115
re-bba/ExiClock.py
Normal file
@ -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()
|
@ -1,60 +1,35 @@
|
||||
|
||||
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).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)
|
||||
with m.If(self.exiClkState == ClockState.FALLING):
|
||||
m.d.sync += self.data.eq(self.data.shift_left(1) | self.inb )
|
||||
|
||||
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()
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user