From 156c2960c8f768fdc3b34b6d690046568be80dea Mon Sep 17 00:00:00 2001 From: Romain Dolbeau Date: Sun, 13 Jun 2021 12:42:35 -0400 Subject: [PATCH] more stuff, with some weird bugs... --- sbus-to-ztex-gateware-migen/sbus-to-fpga.py | 68 +++-- .../sbus_to_fpga_slave.py | 273 +++++++++++++++--- 2 files changed, 284 insertions(+), 57 deletions(-) diff --git a/sbus-to-ztex-gateware-migen/sbus-to-fpga.py b/sbus-to-ztex-gateware-migen/sbus-to-fpga.py index 3fdc22b..b20c632 100644 --- a/sbus-to-ztex-gateware-migen/sbus-to-fpga.py +++ b/sbus-to-ztex-gateware-migen/sbus-to-fpga.py @@ -8,6 +8,7 @@ from litex.soc.integration.soc import * from litex.soc.integration.soc_core import * from litex.soc.integration.builder import * from litex.soc.cores.clock import * +from litex.soc.cores.led import LedChaser from litex_boards.platforms import ztex213 from sbus_to_fpga_slave import *; @@ -29,7 +30,7 @@ _sbus_sbus = [ ("SBUS_3V3_ACKs", 0, Pins("M6 L6 N4"), IOStandard("lvttl")), ("SBUS_3V3_SIZ", 0, Pins("R7 U3 V1"), IOStandard("lvttl")), ("SBUS_3V3_D", 0, Pins("J18 K16 J17 K15 K13 J15 J13 J14 H14 H17 G14 G17 G16 G18 H16 F18 F16 E18 F15 D18 E17 G13 D17 F13 F14 E16 E15 C17 C16 A18 B18 C15"), IOStandard("lvttl")), - ("SBUS_3V3_PA", 0, Pins(" B16 B17 D14 C14 D12 A16 A15 B14 B13 B12 C12 A14 A13 B11 A11 M4 R2 M3 P2 M2 N2 K5 N1 L4 M1 L3 L1 K3"), IOStandard("lvttl")), + ("SBUS_3V3_PA", 0, Pins("B16 B17 D14 C14 D12 A16 A15 B14 B13 B12 C12 A14 A13 B11 A11 M4 R2 M3 P2 M2 N2 K5 N1 L4 M1 L3 L1 K3"), IOStandard("lvttl")), ] # CRG ---------------------------------------------------------------------------------------------- @@ -37,33 +38,39 @@ class _CRG(Module): def __init__(self, platform, sys_clk_freq): self.clock_domains.cd_sys = ClockDomain() self.clock_domains.cd_native = ClockDomain(reset_less=True) - self.clock_domains.cd_sbus = ClockDomain() + #self.clock_domains.cd_sbus = ClockDomain() self.clock_domains.cd_por = ClockDomain() # # # clk48 = platform.request("clk48") + self.cd_native.clk = clk48 clk_sbus = platform.request("SBUS_3V3_CLK") + self.cd_sys.clk = clk_sbus + rst_sbus = platform.request("SBUS_3V3_RSTs") - self.submodules.pll = pll = S7MMCM(speedgrade=-1) - pll.register_clkin(clk48, 48e6) - pll.create_clkout(self.cd_sys, sys_clk_freq) + #self.submodules.pll = pll = S7MMCM(speedgrade=-1) + #pll.register_clkin(clk48, 48e6) + #pll.create_clkout(self.cd_sys, sys_clk_freq) - self.comb += self.cd_sbus.clk.eq(clk_sbus) - self.comb += self.cd_sbus.rst.eq(~platform.request("SBUS_3V3_RSTs")) + #self.comb += self.cd_sbus.clk.eq(clk_sbus) + #self.comb += self.cd_sbus.rst.eq(~rst_sbus) + + #self.comb += self.cd_sys.clk.eq(clk_sbus) + self.comb += self.cd_sys.rst.eq(~rst_sbus) - self.comb += self.cd_native.clk.eq(clk48) + #self.comb += self.cd_native.clk.eq(clk48) - platform.add_false_path_constraints(self.cd_native.clk, self.cd_sbus.clk) - - # FIXME: add SBUS_3V3_RSTs + #platform.add_false_path_constraints(self.cd_native.clk, self.cd_sbus.clk) + platform.add_false_path_constraints(self.cd_native.clk, self.cd_sys.clk) + platform.add_false_path_constraints(self.cd_sys.clk, self.cd_native.clk) # Power on reset, 20 seconds - por_count = Signal(30, reset=20*48*1000000) - por_done = Signal() - self.comb += self.cd_por.clk.eq(clk48) - self.comb += por_done.eq(por_count == 0) - self.sync.por += If(~por_done, por_count.eq(por_count - 1)) - self.comb += pll.reset.eq(~por_done) + #por_count = Signal(30, reset=20*48*1000000) + #por_done = Signal() + #self.comb += self.cd_por.clk.eq(clk48) + #self.comb += por_done.eq(por_count == 0) + #self.sync.por += If(~por_done, por_count.eq(por_count - 1)) + #self.comb += pll.reset.eq(~por_done) class SBusFPGA(SoCCore): def __init__(self, **kwargs): @@ -73,14 +80,24 @@ class SBusFPGA(SoCCore): kwargs["with_uart"] = True kwargs["with_timer"] = False - self.sys_clk_freq = sys_clk_freq = 100e6 + self.sys_clk_freq = sys_clk_freq = 25e6 # SBus max self.platform = platform = ztex213.Platform(variant="ztex2.13a", expansion="sbus") self.platform.add_extension(_sbus_sbus) SoCCore.__init__(self, platform=platform, sys_clk_freq=sys_clk_freq, clk_freq=sys_clk_freq, **kwargs) + wb_mem_map = { + "prom": 0x00000000, + "csr" : 0x00040000, + } + self.mem_map.update(wb_mem_map) self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq) self.platform.add_period_constraint(self.platform.lookup_request("SBUS_3V3_CLK", loose=True), 1e9/25e6) +# self.submodules.leds = LedChaser( +# pads = platform.request_all("user_led"), +# sys_clk_freq = sys_clk_freq) +# self.add_csr("leds") + prom_file = "prom_mini.fc" prom_data = soc_core.get_mem_data(prom_file, "big") prom = Array(prom_data) @@ -88,15 +105,26 @@ class SBusFPGA(SoCCore): #for i in range(len(prom)): # print(hex(prom[i])) #print("\n****************************************\n") - #self.add_ram("prom", origin=0x0, size=2**14, contents=prom_data, mode="r") + self.add_ram("prom", origin=self.mem_map["prom"], size=2**16, contents=prom_data, mode="r") # for show #getattr(self,"prom").mem.init = prom_data #getattr(self,"prom").mem.depth = 2**14 + # don't enable anything on the SBus side for 20 seconds after power up + # this avoids FPGA initialization messing with the cold boot process + # requires us to reset the SPARCstation afterward so the FPGA board + # is properly identified hold_reset_ctr = Signal(30, reset=960000000) self.sync.native += If(hold_reset_ctr>0, hold_reset_ctr.eq(hold_reset_ctr - 1)) hold_reset = Signal(reset=1) self.comb += hold_reset.eq(~(hold_reset_ctr == 0)) - self.submodules.slave = ClockDomainsRenamer("sbus")(SBusFPGASlave(platform=self.platform, soc=self, prom=prom, hold_reset=hold_reset)) + + #self.submodules.sbus_slave = ClockDomainsRenamer("sbus")(SBusFPGASlave(platform=self.platform, soc=self, prom=prom, hold_reset=hold_reset)) + self.submodules.sbus_slave = SBusFPGASlave(platform=self.platform, + prom=prom, + hold_reset=hold_reset, + wishbone=wishbone.Interface(data_width=self.bus.data_width, adr_width=self.bus.address_width)) + + self.bus.add_master(name="SBusBridgeToWishbone", master=self.sbus_slave.wishbone) # self.soc = Module() # self.soc.mem_regions = self.mem_regions = {} diff --git a/sbus-to-ztex-gateware-migen/sbus_to_fpga_slave.py b/sbus-to-ztex-gateware-migen/sbus_to_fpga_slave.py index 5cd19ad..b165504 100644 --- a/sbus-to-ztex-gateware-migen/sbus_to_fpga_slave.py +++ b/sbus-to-ztex-gateware-migen/sbus_to_fpga_slave.py @@ -2,6 +2,7 @@ from migen import * from migen.genlib.fifo import SyncFIFOBuffered from migen.fhdl.specials import Tristate +from litex.soc.interconnect import wishbone SIZ_WORD = 0x0 SIZ_BYTE = 0x1 @@ -21,6 +22,14 @@ ACK_DWORD = 0x2 ACK_HWORD = 0x1 ACK_RECV = 0x0 +ADDR_PHYS_HIGH = 27 +ADDR_PHYS_LOW = 0 +ADDR_PFX_HIGH = ADDR_PHYS_HIGH +ADDR_PFX_LOW = 16 ## 64 KiB per prefix +ADDR_PFX_LENGTH = 12 #(1 + ADDR_PFX_HIGH - ADDR_PFX_LOW) +ROM_ADDR_PFX = C(0x000)[0:12] +WISHBONE_CSR_ADDR_PFX = C(0x004)[0:12] + def siz_is_word(siz): return (SIZ_WORD == siz) or (SIZ_BURST2 == siz) or (SIZ_BURST4 == siz) or (SIZ_BURST8 == siz) or (SIZ_BURST16 == siz) @@ -50,18 +59,93 @@ def siz_to_burst_size_m1(siz): return 15 return 1 -# siz_to_burst_size_m1 = { -# SIZ_WORD: 0, -# SIZ_BURST2: 1, -# SIZ_BURST4: 3, -# SIZ_BURST8: 7, -# SIZ_BURST16: 15 -# }; +class LedDisplay(Module): + def __init__(self, pads): + n = len(pads) + self.value = Signal(32, reset = 0x18244281) + old_value = Signal(32) + display = Signal(8) + + self.submodules.fsm = fsm = FSM(reset_state="Reset") + time_counter = Signal(32, reset = 0) + blink_counter = Signal(4, reset = 0) + self.comb += pads.eq(display) + fsm.act("Reset", + NextValue(time_counter, 25000000//10), + NextValue(blink_counter, 10), + NextValue(display, 0x00), + NextValue(old_value, self.value), + NextState("Quick")) + fsm.act("Quick", + If (old_value != self.value, + NextState("Reset") + ).Elif(time_counter == 0, + If (blink_counter == 0, + NextValue(time_counter, 25000000//2), + NextValue(display, self.value[0:8]), + NextState("Byte0") + ).Else( + NextValue(display, ~display), + NextValue(time_counter, 25000000//10), + NextValue(blink_counter, blink_counter - 1) + ) + ).Else( + NextValue(time_counter, time_counter - 1) + ) + ) + fsm.act("Byte0", + If (old_value != self.value, + NextState("Reset") + ).Elif(time_counter == 0, + NextValue(time_counter, 25000000//2), + NextValue(display, self.value[8:16]), + NextState("Byte1") + ).Else( + NextValue(time_counter, time_counter - 1) + ) + ) + fsm.act("Byte1", + If (old_value != self.value, + NextState("Reset") + ).Elif(time_counter == 0, + NextValue(time_counter, 25000000//2), + NextValue(display, self.value[16:24]), + NextState("Byte2") + ).Else( + NextValue(time_counter, time_counter - 1) + ) + ) + fsm.act("Byte2", + If (old_value != self.value, + NextState("Reset") + ).Elif(time_counter == 0, + NextValue(time_counter, 25000000//2), + NextValue(display, self.value[24:32]), + NextState("Byte3") + ).Else( + NextValue(time_counter, time_counter - 1) + ) + ) + fsm.act("Byte3", + If (old_value != self.value, + NextState("Reset") + ).Elif(time_counter == 0, + NextValue(time_counter, 25000000//10), + NextValue(blink_counter, 10), + NextValue(display, 0x00), + NextState("Quick") + ).Else( + NextValue(time_counter, time_counter - 1) + ) + ) class SBusFPGASlave(Module): - def __init__(self, platform, soc, prom, hold_reset): - + def __init__(self, platform, prom, hold_reset, wishbone): + self.platform = platform self.hold_reset = hold_reset + self.wishbone = wishbone + + self.submodules.led_display = LedDisplay(pads=platform.request_all("user_led")) #pad_SBUS_3V3_CLK = platform.request("SBUS_3V3_CLK") pad_SBUS_3V3_ASs = platform.request("SBUS_3V3_ASs") @@ -80,16 +164,18 @@ class SBusFPGASlave(Module): pad_SBUS_3V3_SIZ = platform.request("SBUS_3V3_SIZ") pad_SBUS_3V3_D = platform.request("SBUS_3V3_D") pad_SBUS_3V3_PA = platform.request("SBUS_3V3_PA") + assert len(pad_SBUS_3V3_D) == 32, "len(pad_SBUS_3V3_D) should be 32" + assert len(pad_SBUS_3V3_PA) == 28, "len(pad_SBUS_3V3_PA) should be 28" - leds = Signal(8, reset=0xF0) - self.comb += platform.request("user_led", 0).eq(leds[0]) - self.comb += platform.request("user_led", 1).eq(leds[1]) - self.comb += platform.request("user_led", 2).eq(leds[2]) - self.comb += platform.request("user_led", 3).eq(leds[3]) - self.comb += platform.request("user_led", 4).eq(leds[4]) - self.comb += platform.request("user_led", 5).eq(leds[5]) - self.comb += platform.request("user_led", 6).eq(leds[6]) - self.comb += platform.request("user_led", 7).eq(leds[7]) + #leds = Signal(8, reset=0xF0) + #self.comb += platform.request("user_led", 0).eq(leds[0]) + #self.comb += platform.request("user_led", 1).eq(leds[1]) + #self.comb += platform.request("user_led", 2).eq(leds[2]) + #self.comb += platform.request("user_led", 3).eq(leds[3]) + #self.comb += platform.request("user_led", 4).eq(leds[4]) + #self.comb += platform.request("user_led", 5).eq(leds[5]) + #self.comb += platform.request("user_led", 6).eq(leds[6]) + #self.comb += platform.request("user_led", 7).eq(leds[7]) sbus_oe_data = Signal(reset=0) sbus_oe_slave_in = Signal(reset=0) @@ -143,7 +229,11 @@ class SBusFPGASlave(Module): self.submodules.slave_fsm = slave_fsm = FSM(reset_state="Reset") - p_data = Signal(32) # prom data + p_data = Signal(32) # prom data to read + + csr_data_w_data = Signal(32) # csr data to write + csr_data_w_addr = Signal(32) # address thereof + csr_data_w_we = Signal(reset = 0) # write enable slave_fsm.act("Reset", NextValue(SBUS_DATA_OE_LED_o, 0), @@ -155,7 +245,7 @@ class SBusFPGASlave(Module): NextValue(sbus_oe_master_in, 0), NextValue(sbus_oe_master_br, 0), NextValue(p_data, 0), - NextValue(leds, 0x0F), + #NextValue(leds, 0x0F), NextState("Start") ) slave_fsm.act("Start", @@ -168,7 +258,7 @@ class SBusFPGASlave(Module): NextValue(sbus_oe_master_in, 0), NextValue(sbus_oe_master_br, 0), NextValue(p_data, 0), - NextValue(leds, 0x01), + #NextValue(leds, 0x01), If((self.hold_reset == 0), NextState("Idle")) ) slave_fsm.act("Idle", @@ -176,47 +266,80 @@ class SBusFPGASlave(Module): If(((SBUS_3V3_SELs_i == 0) and (SBUS_3V3_ASs_i == 0) and (siz_is_word(SBUS_3V3_SIZ_i)) and - (SBUS_3V3_PPRD_i == 1)), + (SBUS_3V3_PPRD_i == 1) and + (SBUS_3V3_PA_i[0:2] == 0)), NextValue(SBUS_DATA_OE_LED_o, 1), + NextValue(SBUS_DATA_OE_LED_2_o, 0), NextValue(sbus_oe_master_in, 1), NextValue(sbus_last_pa, SBUS_3V3_PA_i), NextValue(burst_counter, 0), NextValue(burst_limit_m1, siz_to_burst_size_m1(SBUS_3V3_SIZ_i)), - If((SBUS_3V3_PA_i[16:28] == 0x000), + If((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX), NextValue(SBUS_3V3_ACKs_o, ACK_WORD), NextValue(SBUS_3V3_ERRs_o, 1), - NextValue(p_data, prom[SBUS_3V3_PA_i[2:16]]), + NextValue(p_data, prom[SBUS_3V3_PA_i[ADDR_PHYS_LOW+2:ADDR_PFX_LOW]]), NextState("Slave_Ack_Read_Prom_Burst") + ).Elif((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == WISHBONE_CSR_ADDR_PFX), + NextValue(SBUS_3V3_ACKs_o, ACK_WORD), + NextValue(SBUS_3V3_ERRs_o, 1), + NextValue(self.led_display.value, Cat(SBUS_3V3_PA_i, C(1)[0:2], SBUS_3V3_PA_i[1:2], SBUS_3V3_PPRD_i)), + NextValue(p_data, Cat(SBUS_3V3_PA_i, C(1)[0:2], SBUS_3V3_PA_i[1:2], SBUS_3V3_PPRD_i)), # FIXME + NextState("Slave_Ack_Read_Reg_Burst") ).Else( + NextValue(self.led_display.value, Cat(SBUS_3V3_PA_i, C(1)[0:2], SBUS_3V3_PA_i[1:2], SBUS_3V3_PPRD_i)), NextValue(SBUS_3V3_ACKs_o, ACK_ERR), NextValue(SBUS_3V3_ERRs_o, 1), NextState("Slave_Error") ) ).Elif(((SBUS_3V3_SELs_i == 0) and - (SBUS_3V3_ASs_i == 0) and - (SIZ_BYTE == SBUS_3V3_SIZ_i) and - (SBUS_3V3_PPRD_i == 1)), + (SBUS_3V3_ASs_i == 0) and + (SIZ_BYTE == SBUS_3V3_SIZ_i) and + (SBUS_3V3_PPRD_i == 1)), + NextValue(SBUS_DATA_OE_LED_o, 1), + NextValue(SBUS_DATA_OE_LED_2_o, 0), + NextValue(sbus_oe_master_in, 1), + NextValue(sbus_last_pa, SBUS_3V3_PA_i), + If((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == ROM_ADDR_PFX), + NextValue(SBUS_3V3_ACKs_o, ACK_BYTE), + NextValue(SBUS_3V3_ERRs_o, 1), + NextValue(p_data, prom[SBUS_3V3_PA_i[ADDR_PHYS_LOW+2:ADDR_PFX_LOW]]), + NextState("Slave_Ack_Read_Prom_Byte") + ).Else( + NextValue(self.led_display.value, Cat(SBUS_3V3_PA_i, C(2)[0:2], SBUS_3V3_PA_i[1:2], SBUS_3V3_PPRD_i)), + NextValue(SBUS_3V3_ACKs_o, ACK_ERR), + NextValue(SBUS_3V3_ERRs_o, 1), + NextState("Slave_Error") + ) + ).Elif(((SBUS_3V3_SELs_i == 0) and + (SBUS_3V3_ASs_i == 0) and + (siz_is_word(SBUS_3V3_SIZ_i)) and + (SBUS_3V3_PPRD_i == 0) and + (SBUS_3V3_PA_i[0:2] == 0)), + NextValue(SBUS_DATA_OE_LED_o, 0), NextValue(SBUS_DATA_OE_LED_2_o, 1), NextValue(sbus_oe_master_in, 1), NextValue(sbus_last_pa, SBUS_3V3_PA_i), - If((SBUS_3V3_PA_i[16:28] == 0x000), - NextValue(SBUS_3V3_ACKs_o, ACK_BYTE), + NextValue(burst_counter, 0), + NextValue(burst_limit_m1, siz_to_burst_size_m1(SBUS_3V3_SIZ_i)), + If((SBUS_3V3_PA_i[ADDR_PFX_LOW:ADDR_PFX_LOW+ADDR_PFX_LENGTH] == WISHBONE_CSR_ADDR_PFX), + NextValue(SBUS_3V3_ACKs_o, ACK_WORD), NextValue(SBUS_3V3_ERRs_o, 1), - NextValue(p_data, prom[SBUS_3V3_PA_i[2:16]]), - NextState("Slave_Ack_Read_Prom_Byte") + NextState("Slave_Ack_Reg_Write_Burst") ).Else( + NextValue(self.led_display.value, Cat(SBUS_3V3_PA_i, C(3)[0:2], SBUS_3V3_PA_i[1:2], SBUS_3V3_PPRD_i)), NextValue(SBUS_3V3_ACKs_o, ACK_ERR), NextValue(SBUS_3V3_ERRs_o, 1), NextState("Slave_Error") ) ) ) + # ##### READ ##### slave_fsm.act("Slave_Ack_Read_Prom_Burst", - NextValue(leds, 0x03), + #NextValue(leds, 0x03), NextValue(sbus_oe_data, 1), NextValue(SBUS_3V3_D_o, p_data), - #NextValue(burst_index, index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[2:6])), - NextValue(p_data, prom[Cat(index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[2:6]), sbus_last_pa[6:16])]), + #NextValue(burst_index, index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[ADDR_PHYS_LOW+2:ADDR_PHYS_LOW+6])), + NextValue(p_data, prom[Cat(index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[ADDR_PHYS_LOW+2:ADDR_PHYS_LOW+6]), sbus_last_pa[ADDR_PHYS_LOW+6:ADDR_PFX_LOW])]), If((burst_counter == burst_limit_m1), NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), NextState("Slave_Do_Read") @@ -226,7 +349,7 @@ class SBusFPGASlave(Module): ) ) slave_fsm.act("Slave_Ack_Read_Prom_Byte", - NextValue(leds, 0x0c), + #NextValue(leds, 0x0c), NextValue(sbus_oe_data, 1), If((sbus_last_pa[0:2] == 0x0), NextValue(SBUS_3V3_D_o, Cat(C(0)[0:24], p_data[24:32])) @@ -240,7 +363,7 @@ class SBusFPGASlave(Module): NextState("Slave_Do_Read") ) slave_fsm.act("Slave_Do_Read", - NextValue(leds, 0x30), + #NextValue(leds, 0x30), NextValue(sbus_oe_int1, 0), NextValue(sbus_oe_int7, 0), NextValue(sbus_oe_data, 0), @@ -251,8 +374,53 @@ class SBusFPGASlave(Module): NextState("Idle") ) ) + slave_fsm.act("Slave_Ack_Read_Reg_Burst", + #NextValue(leds, 0x03), + NextValue(sbus_oe_data, 1), + NextValue(SBUS_3V3_D_o, p_data), # FIXME + NextValue(p_data, Cat(C(0)[0:2],index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[ADDR_PHYS_LOW+2:ADDR_PHYS_LOW+6]), sbus_last_pa[ADDR_PHYS_LOW+6:ADDR_PHYS_HIGH+1], C(0)[0:2], SBUS_3V3_PA_i[1:2], SBUS_3V3_PPRD_i)), # FIXME + If((burst_counter == burst_limit_m1), + NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), + NextState("Slave_Do_Read") + ).Else( + NextValue(SBUS_3V3_ACKs_o, ACK_WORD), + NextValue(burst_counter, burst_counter + 1) + ) + ) + # ##### WRITE ##### + slave_fsm.act("Slave_Ack_Reg_Write_Burst", + #NextValue(leds, 0x03), + #NextValue(burst_index, index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[ADDR_PHYS_LOW+2:ADDR_PHYS_LOW+6])), + NextValue(csr_data_w_data, SBUS_3V3_D_i), + NextValue(csr_data_w_addr, Cat(C(0)[0:2], + index_with_wrap((burst_counter+1), burst_limit_m1, sbus_last_pa[ADDR_PHYS_LOW+2:ADDR_PHYS_LOW+6]), + sbus_last_pa[ADDR_PHYS_LOW+6:ADDR_PFX_LOW], + WISHBONE_CSR_ADDR_PFX)), + NextValue(csr_data_w_we, 1), + If((burst_counter == burst_limit_m1), + NextValue(SBUS_3V3_ACKs_o, ACK_IDLE), + NextState("Slave_Ack_Reg_Write_Final") + ).Else( + NextValue(SBUS_3V3_ACKs_o, ACK_WORD), + NextValue(burst_counter, burst_counter + 1) + ) + ) + slave_fsm.act("Slave_Ack_Reg_Write_Final", + NextValue(sbus_oe_int1, 0), + NextValue(sbus_oe_int7, 0), + NextValue(sbus_oe_data, 0), + NextValue(sbus_oe_slave_in, 0), + NextValue(sbus_oe_master_in, 0), + NextValue(sbus_oe_master_br, 0), + If((SBUS_3V3_ASs_i == 1), + NextState("Idle") + ) + ) + # ##### ERROR ##### slave_fsm.act("Slave_Error", - NextValue(leds, 0xc0), + #NextValue(leds, 0xc0), + NextValue(SBUS_DATA_OE_LED_o, 1), + NextValue(SBUS_DATA_OE_LED_2_o, 1), NextValue(sbus_oe_int1, 0), NextValue(sbus_oe_int7, 0), NextValue(sbus_oe_data, 0), @@ -263,3 +431,34 @@ class SBusFPGASlave(Module): NextState("Idle") ) ) + + # ##### Iface to WB ##### + + + self.submodules.wb_fsm = wb_fsm = FSM(reset_state="Reset") + wb_fsm.act("Reset", + self.wishbone.we.eq(0), + self.wishbone.cyc.eq(0), + self.wishbone.stb.eq(0), + self.wishbone.sel.eq(2**len(self.wishbone.sel)-1), + NextState("Idle") + ) + wb_fsm.act("Idle", + If(csr_data_w_we, + self.wishbone.adr.eq(csr_data_w_addr), + self.wishbone.dat_w.eq(csr_data_w_data), + self.wishbone.we.eq(1), + self.wishbone.cyc.eq(1), + self.wishbone.stb.eq(1), + NextValue(csr_data_w_we, 0), + NextState("Wait") + ) + ) + wb_fsm.act("Wait", + If(self.wishbone.ack, + self.wishbone.we.eq(0), + self.wishbone.cyc.eq(0), + self.wishbone.stb.eq(0), + NextState("Idle") + ) + )