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,61 +1,36 @@
|
|||||||
|
|
||||||
import enum
|
|
||||||
import sys
|
|
||||||
import os
|
import os
|
||||||
from amaranth import *
|
from amaranth import *
|
||||||
|
from amaranth.build import Platform
|
||||||
from amaranth.back import verilog
|
from amaranth.back import verilog
|
||||||
from amaranth.sim import Simulator
|
from amaranth.sim import Simulator
|
||||||
|
from ExiClock import ClockState
|
||||||
|
|
||||||
#####
|
#####
|
||||||
# Hardware Description.
|
# Hardware Description.
|
||||||
#####
|
#####
|
||||||
|
|
||||||
class ClockState(enum.Enum):
|
|
||||||
LOW = 0
|
|
||||||
FALLING = 1
|
|
||||||
HIGH = 2
|
|
||||||
RISING = 3
|
|
||||||
|
|
||||||
class ShiftRegister(Elaboratable):
|
class ShiftRegister(Elaboratable):
|
||||||
def __init__(self, width):
|
def __init__(self, width):
|
||||||
self.width = width
|
self.width = width
|
||||||
|
|
||||||
# Ports
|
# Ports
|
||||||
self.nen = Signal()
|
self.nen = Signal()
|
||||||
|
self.exiClkState = Signal(2)
|
||||||
self.rst = Signal()
|
self.rst = Signal()
|
||||||
|
|
||||||
self.inb = Signal()
|
self.inb = Signal()
|
||||||
self.exiClk = Signal()
|
|
||||||
self.data = Signal(self.width, reset=0)
|
self.data = Signal(self.width, reset=0)
|
||||||
|
|
||||||
# State
|
def elaborate(self, platform: Platform):
|
||||||
self.prevExiClkValid = Signal()
|
|
||||||
self.prevExiClk = Signal()
|
|
||||||
self.prevExiClkState = Signal(2)
|
|
||||||
self.exiClkState = Signal(2)
|
|
||||||
|
|
||||||
def elaborate(self, platform):
|
|
||||||
m = Module()
|
m = Module()
|
||||||
|
|
||||||
with m.If(self.rst):
|
with m.If(self.rst):
|
||||||
m.d.sync += self.data.eq(self.data.reset)
|
m.d.sync += self.data.eq(self.data.reset)
|
||||||
|
|
||||||
with m.If(~self.nen):
|
with m.If(~self.nen):
|
||||||
with m.If(self.prevExiClkValid):
|
with m.If(self.exiClkState == ClockState.FALLING):
|
||||||
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.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
|
return m
|
||||||
|
|
||||||
#####
|
#####
|
||||||
@ -133,6 +108,10 @@ class TestBench:
|
|||||||
with sim.write_vcd(os.path.dirname(os.path.abspath(__file__)) + "/ShiftRegister_shift.vcd"):
|
with sim.write_vcd(os.path.dirname(os.path.abspath(__file__)) + "/ShiftRegister_shift.vcd"):
|
||||||
sim.run()
|
sim.run()
|
||||||
|
|
||||||
|
#####
|
||||||
|
# Main portion
|
||||||
|
#####
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
if(len(sys.argv) == 2):
|
if(len(sys.argv) == 2):
|
||||||
|
|
||||||
@ -149,11 +128,6 @@ def main():
|
|||||||
bench = TestBench()
|
bench = TestBench()
|
||||||
bench.simulate()
|
bench.simulate()
|
||||||
|
|
||||||
|
|
||||||
#####
|
|
||||||
# Main portion
|
|
||||||
#####
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
@ -4,9 +4,10 @@ from amaranth import *
|
|||||||
from amaranth.back import verilog
|
from amaranth.back import verilog
|
||||||
from amaranth.build.plat import Platform
|
from amaranth.build.plat import Platform
|
||||||
from amaranth.sim import Simulator
|
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):
|
class ReBba(Elaboratable):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
@ -25,6 +26,8 @@ class ReBba(Elaboratable):
|
|||||||
btn2 = platform.request("button", 2)
|
btn2 = platform.request("button", 2)
|
||||||
btn3 = platform.request("button", 3)
|
btn3 = platform.request("button", 3)
|
||||||
|
|
||||||
|
exiClk = ExiClock()
|
||||||
|
m.submodules += exiClk
|
||||||
sr = ShiftRegister(5)
|
sr = ShiftRegister(5)
|
||||||
m.submodules += sr
|
m.submodules += sr
|
||||||
|
|
||||||
@ -34,11 +37,12 @@ class ReBba(Elaboratable):
|
|||||||
m.d.comb += led4.eq(sr.data[3])
|
m.d.comb += led4.eq(sr.data[3])
|
||||||
m.d.comb += led5.eq(sr.data[4])
|
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.rst.eq(btn2)
|
||||||
m.d.comb += sr.inb.eq(btn1)
|
m.d.comb += sr.inb.eq(btn1)
|
||||||
|
|
||||||
m.d.comb += sr.nen.eq(Const(0))
|
m.d.comb += sr.nen.eq(Const(0))
|
||||||
|
m.d.comb += sr.exiClkState.eq(exiClk.exiClkState)
|
||||||
|
|
||||||
return m
|
return m
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user