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 | ||||
| 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() | ||||
| 
 | ||||
| @ -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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user