still some issues on registers, master mode draft
This commit is contained in:
@@ -64,20 +64,21 @@ def siz_to_burst_size_m1(siz):
|
||||
return 1
|
||||
|
||||
class LedDisplay(Module):
|
||||
def __init__(self, pads):
|
||||
n = len(pads)
|
||||
def __init__(self): #, pads
|
||||
#n = len(pads)
|
||||
n = 8
|
||||
self.value = Signal(32, reset = 0x18244281)
|
||||
old_value = Signal(32)
|
||||
display = Signal(8)
|
||||
self.display = Signal(8)
|
||||
#self.comb += pads.eq(self.display)
|
||||
|
||||
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(self.display, 0x00),
|
||||
NextValue(old_value, self.value),
|
||||
NextState("Quick"))
|
||||
fsm.act("Quick",
|
||||
@@ -86,10 +87,10 @@ class LedDisplay(Module):
|
||||
).Elif(time_counter == 0,
|
||||
If (blink_counter == 0,
|
||||
NextValue(time_counter, 25000000//2),
|
||||
NextValue(display, self.value[0:8]),
|
||||
NextValue(self.display, self.value[0:8]),
|
||||
NextState("Byte0")
|
||||
).Else(
|
||||
NextValue(display, ~display),
|
||||
NextValue(self.display, ~self.display),
|
||||
NextValue(time_counter, 25000000//10),
|
||||
NextValue(blink_counter, blink_counter - 1)
|
||||
)
|
||||
@@ -102,7 +103,7 @@ class LedDisplay(Module):
|
||||
NextState("Reset")
|
||||
).Elif(time_counter == 0,
|
||||
NextValue(time_counter, 25000000//2),
|
||||
NextValue(display, self.value[8:16]),
|
||||
NextValue(self.display, self.value[8:16]),
|
||||
NextState("Byte1")
|
||||
).Else(
|
||||
NextValue(time_counter, time_counter - 1)
|
||||
@@ -113,7 +114,7 @@ class LedDisplay(Module):
|
||||
NextState("Reset")
|
||||
).Elif(time_counter == 0,
|
||||
NextValue(time_counter, 25000000//2),
|
||||
NextValue(display, self.value[16:24]),
|
||||
NextValue(self.display, self.value[16:24]),
|
||||
NextState("Byte2")
|
||||
).Else(
|
||||
NextValue(time_counter, time_counter - 1)
|
||||
@@ -124,7 +125,7 @@ class LedDisplay(Module):
|
||||
NextState("Reset")
|
||||
).Elif(time_counter == 0,
|
||||
NextValue(time_counter, 25000000//2),
|
||||
NextValue(display, self.value[24:32]),
|
||||
NextValue(self.display, self.value[24:32]),
|
||||
NextState("Byte3")
|
||||
).Else(
|
||||
NextValue(time_counter, time_counter - 1)
|
||||
@@ -136,7 +137,7 @@ class LedDisplay(Module):
|
||||
).Elif(time_counter == 0,
|
||||
NextValue(time_counter, 25000000//10),
|
||||
NextValue(blink_counter, 10),
|
||||
NextValue(display, 0x00),
|
||||
NextValue(self.display, 0x00),
|
||||
NextState("Quick")
|
||||
).Else(
|
||||
NextValue(time_counter, time_counter - 1)
|
||||
@@ -144,26 +145,36 @@ class LedDisplay(Module):
|
||||
)
|
||||
|
||||
class SBusFPGABus(Module):
|
||||
def __init__(self, platform, prom, hold_reset, wr_fifo, rd_fifo_addr, rd_fifo_data):
|
||||
def __init__(self, platform, prom, hold_reset, wr_fifo, rd_fifo_addr, rd_fifo_data, master_wr_fifo, master_rd_fifo_addr, master_rd_fifo_data):
|
||||
self.platform = platform
|
||||
self.hold_reset = hold_reset
|
||||
self.wr_fifo = wr_fifo
|
||||
self.rd_fifo_addr = rd_fifo_addr
|
||||
self.rd_fifo_data = rd_fifo_data
|
||||
|
||||
#self.submodules.led_display = LedDisplay(pads=platform.request_all("user_led"))
|
||||
self.master_wr_fifo = master_wr_fifo
|
||||
self.master_rd_fifo_addr = master_rd_fifo_addr
|
||||
self.master_rd_fifo_data = master_rd_fifo_data
|
||||
|
||||
##pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED")
|
||||
##SBUS_DATA_OE_LED_o = Signal()
|
||||
##self.comb += pad_SBUS_DATA_OE_LED.eq(SBUS_DATA_OE_LED_o)
|
||||
##pad_SBUS_DATA_OE_LED_2 = platform.request("SBUS_DATA_OE_LED_2")
|
||||
##SBUS_DATA_OE_LED_2_o = Signal()
|
||||
##self.comb += pad_SBUS_DATA_OE_LED_2.eq(SBUS_DATA_OE_LED_2_o)
|
||||
|
||||
#self.comb += SBUS_DATA_OE_LED_o.eq(~rd_fifo_addr.writable)
|
||||
#self.comb += SBUS_DATA_OE_LED_2_o.eq(rd_fifo_data.readable)
|
||||
|
||||
#pad_SBUS_3V3_CLK = platform.request("SBUS_3V3_CLK")
|
||||
pad_SBUS_3V3_ASs = platform.request("SBUS_3V3_ASs")
|
||||
pad_SBUS_3V3_BGs = platform.request("SBUS_3V3_BGs")
|
||||
pad_SBUS_3V3_BRs = platform.request("SBUS_3V3_BRs")
|
||||
pad_SBUS_3V3_ERRs = platform.request("SBUS_3V3_ERRs")
|
||||
pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED")
|
||||
###pad_SBUS_DATA_OE_LED_2 = platform.request("SBUS_DATA_OE_LED_2")
|
||||
#pad_SBUS_3V3_RSTs = platform.request("SBUS_3V3_RSTs")
|
||||
pad_SBUS_3V3_SELs = platform.request("SBUS_3V3_SELs")
|
||||
#pad_SBUS_3V3_INT1s = platform.request("SBUS_3V3_INT1s")
|
||||
#pad_SBUS_3V3_INT7s = platform.request("SBUS_3V3_INT7s")
|
||||
pad_SBUS_3V3_INT7s = platform.request("SBUS_3V3_INT7s")
|
||||
pad_SBUS_3V3_PPRD = platform.request("SBUS_3V3_PPRD")
|
||||
pad_SBUS_OE = platform.request("SBUS_OE")
|
||||
pad_SBUS_3V3_ACKs = platform.request("SBUS_3V3_ACKs")
|
||||
@@ -176,9 +187,9 @@ class SBusFPGABus(Module):
|
||||
sbus_oe_data = Signal(reset=0)
|
||||
sbus_oe_slave_in = Signal(reset=0)
|
||||
sbus_oe_master_in = Signal(reset=0)
|
||||
sbus_oe_int1 = Signal(reset=0)
|
||||
#sbus_oe_int1 = Signal(reset=0)
|
||||
sbus_oe_int7 = Signal(reset=0)
|
||||
sbus_oe_master_br = Signal(reset=0)
|
||||
#sbus_oe_master_br = Signal(reset=0)
|
||||
|
||||
sbus_last_pa = Signal(28)
|
||||
burst_index = Signal(4)
|
||||
@@ -191,21 +202,18 @@ class SBusFPGABus(Module):
|
||||
SBUS_3V3_BGs_i = Signal()
|
||||
self.comb += SBUS_3V3_BGs_i.eq(pad_SBUS_3V3_BGs)
|
||||
SBUS_3V3_BRs_o = Signal(reset=1)
|
||||
self.specials += Tristate(pad_SBUS_3V3_BRs, SBUS_3V3_BRs_o, sbus_oe_master_br, None)
|
||||
#self.specials += Tristate(pad_SBUS_3V3_BRs, SBUS_3V3_BRs_o, sbus_oe_master_br, None)
|
||||
self.comb += pad_SBUS_3V3_BRs.eq(SBUS_3V3_BRs_o)
|
||||
SBUS_3V3_ERRs_i = Signal()
|
||||
SBUS_3V3_ERRs_o = Signal()
|
||||
self.specials += Tristate(pad_SBUS_3V3_ERRs, SBUS_3V3_ERRs_o, sbus_oe_master_in, SBUS_3V3_ERRs_i)
|
||||
SBUS_DATA_OE_LED_o = Signal()
|
||||
self.comb += pad_SBUS_DATA_OE_LED.eq(SBUS_DATA_OE_LED_o)
|
||||
###SBUS_DATA_OE_LED_2_o = Signal()
|
||||
###self.comb += pad_SBUS_DATA_OE_LED_2.eq(SBUS_DATA_OE_LED_2_o)
|
||||
#SBUS_3V3_RSTs = Signal()
|
||||
SBUS_3V3_SELs_i = Signal()
|
||||
self.comb += SBUS_3V3_SELs_i.eq(pad_SBUS_3V3_SELs)
|
||||
#SBUS_3V3_INT1s_o = Signal(reset=1)
|
||||
#self.specials += Tristate(pad_SBUS_3V3_INT1s, SBUS_3V3_INT1s_o, sbus_oe_int1, None)
|
||||
#SBUS_3V3_INT7s_o = Signal(reset=1)
|
||||
#self.specials += Tristate(pad_SBUS_3V3_INT7s, SBUS_3V3_INT7s_o, sbus_oe_int7, None)
|
||||
SBUS_3V3_INT7s_o = Signal(reset=1)
|
||||
self.specials += Tristate(pad_SBUS_3V3_INT7s, SBUS_3V3_INT7s_o, sbus_oe_int7, None)
|
||||
SBUS_3V3_PPRD_i = Signal()
|
||||
SBUS_3V3_PPRD_o = Signal()
|
||||
self.specials += Tristate(pad_SBUS_3V3_PPRD, SBUS_3V3_PPRD_o, sbus_oe_slave_in, SBUS_3V3_PPRD_i)
|
||||
@@ -230,35 +238,51 @@ class SBusFPGABus(Module):
|
||||
data_read_timeout = Signal(7)
|
||||
data_read_stale = Signal(5, reset = 0)
|
||||
|
||||
master_data = Signal(32) # could be merged with p_data
|
||||
master_addr = Signal(30) # could be meged with data_read_addr
|
||||
|
||||
master_we = Signal();
|
||||
|
||||
# self.submodules.led_display = LedDisplay()
|
||||
# #self.comb += self.led_display.value.eq(Cat(Signal(2, reset=0), master_addr))
|
||||
# self.comb += self.led_display.value.eq(p_data)
|
||||
# old_display = Signal(8)
|
||||
# self.sync += old_display.eq(self.led_display.display)
|
||||
# self.submodules.display_fsm = display_fsm = FSM(reset_state="Reset")
|
||||
# display_fsm.act("Reset",
|
||||
# NextState("Idle"))
|
||||
# display_fsm.act("Idle",
|
||||
# If(old_display != self.led_display.display,
|
||||
# NextState("Update")))
|
||||
# display_fsm.act("Update",
|
||||
# If(self.wr_fifo.writable & SBUS_3V3_ASs_i, ## available space and not in a slave cycle
|
||||
# self.wr_fifo.we.eq(1),
|
||||
# self.wr_fifo.din.eq(Cat(Signal(30, reset=0x00040000), self.led_display.display, Signal(24, reset=0))),
|
||||
# NextState("Idle")))
|
||||
|
||||
# clean the read FIFO from stale data
|
||||
self.submodules.cleaning_fsm = cleaning_fsm = FSM(reset_state="Reset")
|
||||
cleaning_fsm.act("Reset",
|
||||
NextState("Idle"))
|
||||
cleaning_fsm.act("Idle",
|
||||
If(rd_fifo_data.readable & (data_read_stale != 0),
|
||||
rd_fifo_data.re.eq(1),
|
||||
If(self.rd_fifo_data.readable & (data_read_stale != 0),
|
||||
self.rd_fifo_data.re.eq(1),
|
||||
NextValue(data_read_stale, data_read_stale - 1)))
|
||||
self.comb += SBUS_DATA_OE_LED_o.eq(data_read_stale != 0)
|
||||
#self.comb += SBUS_DATA_OE_LED_o.eq(data_read_stale != 0)
|
||||
|
||||
self.submodules.slave_fsm = slave_fsm = FSM(reset_state="Reset")
|
||||
|
||||
slave_fsm.act("Reset",
|
||||
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),
|
||||
NextValue(p_data, 0),
|
||||
NextState("Start")
|
||||
)
|
||||
slave_fsm.act("Start",
|
||||
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),
|
||||
NextValue(p_data, 0),
|
||||
If((self.hold_reset == 0), NextState("Idle"))
|
||||
)
|
||||
@@ -296,7 +320,7 @@ class SBusFPGABus(Module):
|
||||
NextValue(p_data, 0xDEADBEEF),
|
||||
NextValue(data_read_addr, (Cat(SBUS_3V3_PA_i[2:], Signal(4, reset=0)))), # enqueue all the request to the wishbone
|
||||
NextValue(data_read_enable, 1), # enqueue all the request to the wishbone
|
||||
NextValue(data_read_timeout, 0xFF),
|
||||
NextValue(data_read_timeout, 0x7F),
|
||||
NextState("Slave_Ack_Read_Reg_Burst_Wait_For_Data")
|
||||
).Else(
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_ERR),
|
||||
@@ -315,7 +339,6 @@ class SBusFPGABus(Module):
|
||||
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, Signal(2, reset = 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")
|
||||
@@ -345,9 +368,39 @@ class SBusFPGABus(Module):
|
||||
NextValue(SBUS_3V3_ERRs_o, 1),
|
||||
NextState("Slave_Error")
|
||||
)
|
||||
).Elif(SBUS_3V3_BGs_i &
|
||||
(self.master_wr_fifo.readable | self.master_rd_fifo_addr.readable),
|
||||
NextValue(SBUS_3V3_BRs_o, 0)
|
||||
).Elif(~SBUS_3V3_BGs_i &
|
||||
(self.master_wr_fifo.readable | self.master_rd_fifo_addr.readable),
|
||||
NextValue(SBUS_3V3_BRs_o, 1), # relinquish the request
|
||||
NextValue(sbus_oe_data, 1), ## output data (at least for @ during translation)
|
||||
NextValue(sbus_oe_slave_in, 1), ## PPRD, SIZ becomes output
|
||||
NextValue(sbus_oe_master_in, 0), ## ERRs, ACKs are input
|
||||
NextValue(burst_counter, 0),
|
||||
NextValue(burst_limit_m1, 0), ## only single word for now
|
||||
If(self.master_wr_fifo.readable,
|
||||
NextValue(master_addr, self.master_wr_fifo.dout[0:30]),
|
||||
NextValue(master_data, self.master_wr_fifo.dout[30:32]),
|
||||
self.master_wr_fifo.re.eq(1),
|
||||
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.master_wr_fifo.dout[0:30])),
|
||||
NextValue(SBUS_3V3_PPRD_o, 0),
|
||||
NextValue(master_we, 1),
|
||||
NextState("Master_Translation")
|
||||
).Elif(self.master_rd_fifo_addr.readable,
|
||||
NextValue(master_addr, self.master_rd_fifo_addr.dout),
|
||||
self.master_rd_fifo_addr.re.eq(1),
|
||||
NextValue(SBUS_3V3_D_o, Cat(Signal(2, reset = 0), self.master_rd_fifo_addr.dout[0:30])),
|
||||
NextValue(SBUS_3V3_PPRD_o, 1),
|
||||
NextValue(master_we, 0),
|
||||
NextState("Master_Translation")
|
||||
).Else(
|
||||
# FIXME: handle error
|
||||
)
|
||||
|
||||
)
|
||||
)
|
||||
# ##### READ #####
|
||||
# ##### SLAVE READ #####
|
||||
slave_fsm.act("Slave_Ack_Read_Prom_Burst",
|
||||
NextValue(sbus_oe_data, 1),
|
||||
NextValue(SBUS_3V3_D_o, p_data),
|
||||
@@ -374,12 +427,9 @@ class SBusFPGABus(Module):
|
||||
NextState("Slave_Do_Read")
|
||||
)
|
||||
slave_fsm.act("Slave_Do_Read",
|
||||
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")
|
||||
)
|
||||
@@ -392,13 +442,14 @@ class SBusFPGABus(Module):
|
||||
NextState("Slave_Do_Read")
|
||||
).Else(
|
||||
NextValue(burst_counter, burst_counter + 1),
|
||||
If(rd_fifo_data.readable,
|
||||
If(rd_fifo_data.dout[32] == 0,
|
||||
NextValue(p_data, rd_fifo_data.dout),
|
||||
rd_fifo_data.re.eq(1),
|
||||
If(self.rd_fifo_data.readable,
|
||||
If(self.rd_fifo_data.dout[32] == 0,
|
||||
NextValue(p_data, self.rd_fifo_data.dout),
|
||||
self.rd_fifo_data.re.eq(1),
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_WORD)
|
||||
).Else(
|
||||
rd_fifo_data.re.eq(1),
|
||||
self.rd_fifo_data.re.eq(1),
|
||||
NextValue(p_data, self.rd_fifo_data.dout),
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_RERUN),
|
||||
NextValue(data_read_stale, burst_limit_m1 - burst_counter),
|
||||
NextState("Slave_Do_Read"),
|
||||
@@ -411,18 +462,27 @@ class SBusFPGABus(Module):
|
||||
)
|
||||
slave_fsm.act("Slave_Ack_Read_Reg_Burst_Wait_For_Data",
|
||||
NextValue(data_read_timeout, data_read_timeout - 1),
|
||||
If(rd_fifo_data.readable,
|
||||
NextValue(p_data, rd_fifo_data.dout),
|
||||
rd_fifo_data.re.eq(1),
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_WORD),
|
||||
NextState("Slave_Ack_Read_Reg_Burst")
|
||||
If(self.rd_fifo_data.readable,
|
||||
If(self.rd_fifo_data.dout[32] == 0,
|
||||
NextValue(p_data, self.rd_fifo_data.dout),
|
||||
self.rd_fifo_data.re.eq(1),
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_WORD),
|
||||
NextState("Slave_Ack_Read_Reg_Burst")
|
||||
).Else(
|
||||
self.rd_fifo_data.re.eq(1),
|
||||
NextValue(p_data, self.rd_fifo_data.dout),
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_RERUN),
|
||||
NextValue(data_read_stale, burst_limit_m1 - burst_counter),
|
||||
NextState("Slave_Do_Read"),
|
||||
)
|
||||
).Elif(data_read_timeout == 0,
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_RERUN),
|
||||
NextValue(data_read_stale, 1 + burst_limit_m1 - burst_counter),
|
||||
NextState("Slave_Do_Read")
|
||||
NextValue(p_data, 0x00C0FFEE),
|
||||
NextValue(SBUS_3V3_ACKs_o, ACK_RERUN),
|
||||
NextValue(data_read_stale, 1 + burst_limit_m1 - burst_counter),
|
||||
NextState("Slave_Do_Read")
|
||||
)
|
||||
)
|
||||
# ##### WRITE #####
|
||||
# ##### SLAVE WRITE #####
|
||||
slave_fsm.act("Slave_Ack_Reg_Write_Burst",
|
||||
self.wr_fifo.din.eq(Cat(index_with_wrap(burst_counter, burst_limit_m1, sbus_last_pa[ADDR_PHYS_LOW+2:ADDR_PHYS_LOW+6]), # 4 bits, adr FIXME
|
||||
sbus_last_pa[ADDR_PHYS_LOW+6:ADDR_PFX_LOW], # 10 bits, adr
|
||||
@@ -439,30 +499,148 @@ class SBusFPGABus(Module):
|
||||
)
|
||||
)
|
||||
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 ERROR #####
|
||||
slave_fsm.act("Slave_Error",
|
||||
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")
|
||||
)
|
||||
)
|
||||
# ##### MASTER #####
|
||||
slave_fsm.act("Master_Translation",
|
||||
If(master_we,
|
||||
NextValue(sbus_oe_data, 1),
|
||||
NextValue(SBUS_3V3_D_o, master_data)
|
||||
).Else(
|
||||
NextValue(sbus_oe_data, 0)
|
||||
),
|
||||
Case(SBUS_3V3_ACKs_i, {
|
||||
ACK_ERR: ## ouch
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")],
|
||||
ACK_RERUN: ### dunno how to handle that yet, maybe delay the fifo re(1)?
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")],
|
||||
ACK_IDLE:
|
||||
[If(master_we,
|
||||
NextState("Master_Write"),
|
||||
## FIXME: in burst mode, should update master_data with the next value
|
||||
## FIXME: we don't do burst mode yet
|
||||
).Else(
|
||||
NextState("Master_Read"),
|
||||
)],
|
||||
"default":
|
||||
[If(SBUS_3V3_BGs_i, ## oups, we lost our bus access without error ?!?
|
||||
NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
)],
|
||||
})
|
||||
)
|
||||
slave_fsm.act("Master_Read",
|
||||
Case(SBUS_3V3_ACKs_i, {
|
||||
ACK_WORD:
|
||||
[NextState("Master_Read_Ack")
|
||||
],
|
||||
ACK_IDLE:
|
||||
[NextState("Master_Read") ## redundant
|
||||
],
|
||||
ACK_RERUN: ### dunno how to handle that yet, maybe delay the fifo re(1)?
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
],
|
||||
"default": ## ACK_ERRS or other
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
],
|
||||
})
|
||||
)
|
||||
slave_fsm.act("Master_Read_Ack",
|
||||
self.master_rd_fifo_data.we.eq(1),
|
||||
NextValue(self.master_rd_fifo_data.din, SBUS_3V3_D_i),
|
||||
NextValue(burst_counter, burst_counter + 1),
|
||||
If(burst_counter == burst_limit_m1,
|
||||
NextState("Master_Read_Finish")
|
||||
).Else(
|
||||
Case(SBUS_3V3_ACKs_i, {
|
||||
ACK_WORD: NextState("Master_Read_Ack"), ## redundant
|
||||
ACK_IDLE: NextState("Master_Read"),
|
||||
ACK_RERUN: ### dunno how to handle that yet, maybe delay the fifo re(1)?
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
],
|
||||
"default":
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
],
|
||||
}),
|
||||
)
|
||||
)
|
||||
slave_fsm.act("Master_Read_Finish", ## missing the handling of late error
|
||||
NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
)
|
||||
slave_fsm.act("Master_Write",
|
||||
Case(SBUS_3V3_ACKs_i, {
|
||||
ACK_WORD:
|
||||
[If(burst_counter == burst_limit_m1,
|
||||
NextState("Master_Write_Final"),
|
||||
).Else(
|
||||
NextValue(SBUS_3V3_D_o, master_data), ## FIXME: we're not updating master_data for burst mode yet
|
||||
NextValue(burst_counter, burst_counter + 1),
|
||||
)],
|
||||
ACK_IDLE:
|
||||
[NextState("Master_Write") ## redundant
|
||||
],
|
||||
ACK_RERUN: ### dunno how to handle that yet, maybe delay the fifo re(1)?
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
],
|
||||
"default": ## ACK_ERRS or other
|
||||
[NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
],
|
||||
})
|
||||
)
|
||||
slave_fsm.act("Master_Write_Final",
|
||||
NextValue(sbus_oe_data, 0),
|
||||
NextValue(sbus_oe_slave_in, 0),
|
||||
NextValue(sbus_oe_master_in, 0),
|
||||
NextState("Idle")
|
||||
)
|
||||
# ##### FINISHED #####
|
||||
|
||||
self.submodules.request_fsm = request_fsm = FSM(reset_state="Reset")
|
||||
req_counter = Signal(4)
|
||||
req_limit_m1 = Signal(4)
|
||||
request_fsm.act("Reset",
|
||||
NextState("Idle")
|
||||
)
|
||||
@@ -472,16 +650,17 @@ class SBusFPGABus(Module):
|
||||
self.rd_fifo_addr.we.eq(1),
|
||||
self.rd_fifo_addr.din.eq(data_read_addr),
|
||||
If (burst_limit_m1 != burst_counter, # 0 the first time
|
||||
NextValue(burst_counter, burst_counter + 1),
|
||||
NextValue(req_counter, burst_counter + 1),
|
||||
NextValue(req_limit_m1, burst_limit_m1),
|
||||
NextState("Queue")
|
||||
)
|
||||
)
|
||||
)
|
||||
request_fsm.act("Queue",
|
||||
self.rd_fifo_addr.we.eq(1),
|
||||
self.rd_fifo_addr.din.eq(Cat(index_with_wrap(burst_counter, burst_limit_m1, data_read_addr[0:4]), data_read_addr[4:])),
|
||||
If (burst_limit_m1 != burst_counter,
|
||||
NextValue(burst_counter, burst_counter + 1),
|
||||
self.rd_fifo_addr.din.eq(Cat(index_with_wrap(req_counter, req_limit_m1, data_read_addr[0:4]), data_read_addr[4:])),
|
||||
If(req_limit_m1 != req_counter,
|
||||
NextValue(req_counter, req_counter + 1),
|
||||
).Else(
|
||||
NextState("Idle")
|
||||
)
|
||||
|
||||
@@ -37,8 +37,8 @@ _sbus_sbus = [
|
||||
|
||||
_usb_io = [
|
||||
("usb", 0,
|
||||
Subsignal("dp", Pins("E3")), # Serial TX
|
||||
Subsignal("dm", Pins("F3")), # Serial RX
|
||||
Subsignal("dp", Pins("V9")), # Serial TX
|
||||
Subsignal("dm", Pins("U9")), # Serial RX
|
||||
IOStandard("LVCMOS33"))
|
||||
]
|
||||
# CRG ----------------------------------------------------------------------------------------------
|
||||
@@ -99,9 +99,10 @@ class SBusFPGA(SoCCore):
|
||||
self.platform.add_extension(_usb_io)
|
||||
SoCCore.__init__(self, platform=platform, sys_clk_freq=sys_clk_freq, clk_freq=sys_clk_freq, **kwargs)
|
||||
wb_mem_map = {
|
||||
"prom": 0x00000000,
|
||||
"csr" : 0x00040000,
|
||||
"usb_host": 0x00080000,
|
||||
"prom": 0x00000000,
|
||||
"csr" : 0x00040000,
|
||||
"usb_host": 0x00080000,
|
||||
"usb_fake_dma": 0x000c0000,
|
||||
}
|
||||
self.mem_map.update(wb_mem_map)
|
||||
self.submodules.crg = _CRG(platform=platform, sys_clk_freq=sys_clk_freq)
|
||||
@@ -114,6 +115,24 @@ class SBusFPGA(SoCCore):
|
||||
|
||||
self.add_usb_host(pads=platform.request("usb"), usb_clk_freq=48e6)
|
||||
#self.comb += self.cpu.interrupt[16].eq(self.usb_host.interrupt) #fixme: need to deal with interrupts
|
||||
|
||||
pad_SBUS_3V3_INT1s = platform.request("SBUS_3V3_INT1s")
|
||||
SBUS_3V3_INT1s_o = Signal(reset=1)
|
||||
# the 74LVC2G07 takes care of the Z state: 1 -> Z on the bus, 0 -> 0 on the bus (asserted interrupt)
|
||||
self.comb += pad_SBUS_3V3_INT1s.eq(SBUS_3V3_INT1s_o)
|
||||
self.comb += SBUS_3V3_INT1s_o.eq(~self.usb_host.interrupt)
|
||||
|
||||
|
||||
pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED")
|
||||
SBUS_DATA_OE_LED_o = Signal()
|
||||
self.comb += pad_SBUS_DATA_OE_LED.eq(SBUS_DATA_OE_LED_o)
|
||||
#pad_SBUS_DATA_OE_LED_2 = platform.request("SBUS_DATA_OE_LED_2")
|
||||
#SBUS_DATA_OE_LED_2_o = Signal()
|
||||
#self.comb += pad_SBUS_DATA_OE_LED_2.eq(SBUS_DATA_OE_LED_2_o)
|
||||
interrupt_memory = Signal()
|
||||
self.sync += interrupt_memory.eq(interrupt_memory | ~SBUS_3V3_INT1s_o)
|
||||
self.comb += SBUS_DATA_OE_LED_o.eq(interrupt_memory)
|
||||
#self.comb += SBUS_DATA_OE_LED_2_o.eq(~SBUS_3V3_INT1s_o)
|
||||
|
||||
prom_file = "prom_migen.fc"
|
||||
prom_data = soc_core.get_mem_data(prom_file, "big")
|
||||
@@ -150,24 +169,50 @@ class SBusFPGA(SoCCore):
|
||||
sbus_to_wishbone_rd_fifo_data = ClockDomainsRenamer({"write": "sys", "read": "sbus"})(sbus_to_wishbone_rd_fifo_data)
|
||||
self.submodules += sbus_to_wishbone_rd_fifo_data
|
||||
|
||||
# SBus to Wishbone FSM, 'Slave' on the SBus side, 'Master' on the Wishbone side
|
||||
# SBus to Wishbone, 'Slave' on the SBus side, 'Master' on the Wishbone side
|
||||
self.submodules.sbus_to_wishbone = SBusToWishbone(platform=self.platform,
|
||||
wr_fifo=sbus_to_wishbone_wr_fifo,
|
||||
rd_fifo_addr=sbus_to_wishbone_rd_fifo_addr,
|
||||
rd_fifo_data=sbus_to_wishbone_rd_fifo_data,
|
||||
wishbone=wishbone.Interface(data_width=self.bus.data_width))
|
||||
|
||||
|
||||
# FIFO to send data & address from Wishbone to the SBus
|
||||
wishbone_to_sbus_wr_fifo = AsyncFIFOBuffered(width=32+30, depth=16)
|
||||
wishbone_to_sbus_wr_fifo = ClockDomainsRenamer({"write": "sys", "read": "sbus"})(wishbone_to_sbus_wr_fifo)
|
||||
self.submodules += wishbone_to_sbus_wr_fifo
|
||||
|
||||
# FIFOs to send address / receive data from Wishbone to the SBus
|
||||
wishbone_to_sbus_rd_fifo_addr = AsyncFIFOBuffered(width=30, depth=4)
|
||||
wishbone_to_sbus_rd_fifo_addr = ClockDomainsRenamer({"write": "sys", "read": "sbus"})(wishbone_to_sbus_rd_fifo_addr)
|
||||
self.submodules += wishbone_to_sbus_rd_fifo_addr
|
||||
wishbone_to_sbus_rd_fifo_data = AsyncFIFOBuffered(width=32, depth=4)
|
||||
wishbone_to_sbus_rd_fifo_data = ClockDomainsRenamer({"write": "sbus", "read": "sys"})(wishbone_to_sbus_rd_fifo_data)
|
||||
self.submodules += wishbone_to_sbus_rd_fifo_data
|
||||
|
||||
# Wishbone to SBus, 'Master' on the SBus side, 'Slave' on the Wishbone side
|
||||
self.submodules.wishbone_to_sbus = WishboneToSBus(platform=self.platform,
|
||||
soc=self,
|
||||
wr_fifo=wishbone_to_sbus_wr_fifo,
|
||||
rd_fifo_addr=wishbone_to_sbus_rd_fifo_addr,
|
||||
rd_fifo_data=wishbone_to_sbus_rd_fifo_data,
|
||||
wishbone=wishbone.Interface(data_width=self.bus.data_width))
|
||||
|
||||
_sbus_bus = SBusFPGABus(platform=self.platform,
|
||||
prom=prom,
|
||||
hold_reset=hold_reset,
|
||||
wr_fifo=sbus_to_wishbone_wr_fifo,
|
||||
rd_fifo_addr=sbus_to_wishbone_rd_fifo_addr,
|
||||
rd_fifo_data=sbus_to_wishbone_rd_fifo_data,)
|
||||
prom=prom,
|
||||
hold_reset=hold_reset,
|
||||
wr_fifo=sbus_to_wishbone_wr_fifo,
|
||||
rd_fifo_addr=sbus_to_wishbone_rd_fifo_addr,
|
||||
rd_fifo_data=sbus_to_wishbone_rd_fifo_data,
|
||||
master_wr_fifo=wishbone_to_sbus_wr_fifo,
|
||||
master_rd_fifo_addr=wishbone_to_sbus_rd_fifo_addr,
|
||||
master_rd_fifo_data=wishbone_to_sbus_rd_fifo_data)
|
||||
self.submodules.sbus_bus = ClockDomainsRenamer("sbus")(_sbus_bus)
|
||||
|
||||
self.bus.add_master(name="SBusBridgeToWishbone", master=self.sbus_to_wishbone.wishbone)
|
||||
|
||||
# self.soc = Module()
|
||||
self.bus.add_slave(name="usb_fake_dma", slave=self.wishbone_to_sbus.wishbone, region=SoCRegion(origin=self.mem_map.get("usb_fake_dma", None), size=0x10000, cached=False))
|
||||
|
||||
# self.soc = Module()
|
||||
# self.soc.mem_regions = self.mem_regions = {}
|
||||
# region = litex.soc.integration.soc.SoCRegion(origin=0x0, size=0x0)
|
||||
# region.length = 0
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
from migen import *
|
||||
from litex.soc.interconnect import wishbone
|
||||
|
||||
# ********************************************************************************************************
|
||||
class SBusToWishbone(Module):
|
||||
def __init__(self, platform, wr_fifo, rd_fifo_addr, rd_fifo_data, wishbone):
|
||||
self.platform = platform
|
||||
@@ -10,6 +11,9 @@ class SBusToWishbone(Module):
|
||||
self.rd_fifo_data = rd_fifo_data
|
||||
self.wishbone = wishbone
|
||||
|
||||
#pad_SBUS_DATA_OE_LED = platform.request("SBUS_DATA_OE_LED")
|
||||
#SBUS_DATA_OE_LED_o = Signal()
|
||||
#self.comb += pad_SBUS_DATA_OE_LED.eq(SBUS_DATA_OE_LED_o)
|
||||
pad_SBUS_DATA_OE_LED_2 = platform.request("SBUS_DATA_OE_LED_2")
|
||||
SBUS_DATA_OE_LED_2_o = Signal()
|
||||
self.comb += pad_SBUS_DATA_OE_LED_2.eq(SBUS_DATA_OE_LED_2_o)
|
||||
@@ -17,8 +21,10 @@ class SBusToWishbone(Module):
|
||||
data = Signal(32)
|
||||
adr = Signal(30)
|
||||
timeout = Signal(7)
|
||||
|
||||
self.real_hcca = Signal(32)
|
||||
|
||||
# ##### FSM: write to WB #####
|
||||
# ##### FSM: read/write from/to WB #####
|
||||
self.submodules.fsm = fsm = FSM(reset_state="Reset")
|
||||
fsm.act("Reset",
|
||||
self.wishbone.we.eq(0),
|
||||
@@ -27,21 +33,30 @@ class SBusToWishbone(Module):
|
||||
NextState("Idle")
|
||||
)
|
||||
fsm.act("Idle",
|
||||
If (rd_fifo_addr.readable & ~self.wishbone.cyc & self.rd_fifo_data.writable,
|
||||
rd_fifo_addr.re.eq(1),
|
||||
NextValue(adr, self.rd_fifo_addr.dout[0:30]),
|
||||
NextValue(timeout, 127),
|
||||
NextState("Read")
|
||||
).Elif(self.wr_fifo.readable & ~self.wishbone.cyc,
|
||||
self.wr_fifo.re.eq(1),
|
||||
NextValue(adr, self.wr_fifo.dout[0:30]),
|
||||
NextValue(data, self.wr_fifo.dout[30:62]),
|
||||
NextValue(timeout, 127),
|
||||
NextState("Write")
|
||||
# write first, we don't want a read to pass before a previous write
|
||||
If(self.wr_fifo.readable & ~self.wishbone.cyc,
|
||||
self.wr_fifo.re.eq(1),
|
||||
NextValue(adr, self.wr_fifo.dout[0:30]),
|
||||
## need to cheat with the USB HCCA registers
|
||||
If((self.wr_fifo.dout[0:30] == 0x00020006), ## 80018 >> 2 == HCCA register for USB
|
||||
NextValue(SBUS_DATA_OE_LED_2_o, 1),
|
||||
NextValue(self.real_hcca, self.wr_fifo.dout[30:62]),
|
||||
NextValue(data, Cat(self.wr_fifo.dout[30:46], Signal(16, reset=0x000c))) ## 0x000c: are reserved for DMA bridging
|
||||
).Elif((self.wr_fifo.dout[0:30] >= 0x00020007) & (self.wr_fifo.dout[0:30] <= 0x0002000c) & (self.wr_fifo.dout[30:62] != 0),
|
||||
NextValue(data, Cat(self.wr_fifo.dout[30:46], Signal(16, reset=0x000c)))
|
||||
).Else(
|
||||
NextValue(data, self.wr_fifo.dout[30:62])
|
||||
),
|
||||
NextValue(timeout, 127),
|
||||
NextState("Write")
|
||||
).Elif (rd_fifo_addr.readable & ~self.wishbone.cyc & self.rd_fifo_data.writable,
|
||||
rd_fifo_addr.re.eq(1),
|
||||
NextValue(adr, self.rd_fifo_addr.dout[0:30]),
|
||||
NextValue(timeout, 127),
|
||||
NextState("Read")
|
||||
)
|
||||
)
|
||||
fsm.act("Write",
|
||||
SBUS_DATA_OE_LED_2_o.eq(1),
|
||||
self.wishbone.adr.eq(adr),
|
||||
self.wishbone.dat_w.eq(data),
|
||||
self.wishbone.we.eq(1),
|
||||
@@ -62,7 +77,6 @@ class SBusToWishbone(Module):
|
||||
)
|
||||
)
|
||||
fsm.act("Read",
|
||||
SBUS_DATA_OE_LED_2_o.eq(1),
|
||||
self.wishbone.adr.eq(adr),
|
||||
self.wishbone.we.eq(0),
|
||||
self.wishbone.cyc.eq(1),
|
||||
@@ -71,7 +85,11 @@ class SBusToWishbone(Module):
|
||||
NextValue(timeout, timeout - 1),
|
||||
If(self.wishbone.ack,
|
||||
self.rd_fifo_data.we.eq(1),
|
||||
self.rd_fifo_data.din.eq(Cat(self.wishbone.dat_r, Signal(reset = 0))),
|
||||
If((adr >= 0x00020006) & (adr <= 0x0002000c) & (self.wishbone.dat_r != 0), ## 80018 >> 2 == HCCA register for USB
|
||||
self.rd_fifo_data.din.eq(Cat(self.wishbone.dat_r[0:16], self.real_hcca[16:32], Signal(reset = 0)))
|
||||
).Else(
|
||||
self.rd_fifo_data.din.eq(Cat(self.wishbone.dat_r, Signal(reset = 0)))
|
||||
),
|
||||
self.wishbone.we.eq(0),
|
||||
self.wishbone.cyc.eq(0),
|
||||
self.wishbone.stb.eq(0),
|
||||
@@ -85,3 +103,80 @@ class SBusToWishbone(Module):
|
||||
NextState("Idle")
|
||||
)
|
||||
)
|
||||
|
||||
# ********************************************************************************************************
|
||||
class WishboneToSBus(Module):
|
||||
def __init__(self, platform, soc, wr_fifo, rd_fifo_addr, rd_fifo_data, wishbone):
|
||||
self.platform = platform
|
||||
self.wr_fifo = wr_fifo
|
||||
self.rd_fifo_addr = rd_fifo_addr
|
||||
self.rd_fifo_data = rd_fifo_data
|
||||
self.wishbone = wishbone
|
||||
self.soc = soc
|
||||
|
||||
#pad_SBUS_DATA_OE_LED_2 = platform.request("SBUS_DATA_OE_LED_2")
|
||||
#SBUS_DATA_OE_LED_2_o = Signal()
|
||||
#self.comb += pad_SBUS_DATA_OE_LED_2.eq(SBUS_DATA_OE_LED_2_o)
|
||||
|
||||
data = Signal(32)
|
||||
adr = Signal(30)
|
||||
|
||||
self.real_hcca = self.soc.sbus_to_wishbone.real_hcca
|
||||
|
||||
# ##### FSM: read/write from/to SBus #####
|
||||
self.submodules.fsm = fsm = FSM(reset_state="Reset")
|
||||
fsm.act("Reset",
|
||||
NextState("Idle")
|
||||
)
|
||||
fsm.act("Idle",
|
||||
If(self.wishbone.stb & self.wishbone.cyc & self.wishbone.we & self.wr_fifo.writable,
|
||||
If((self.wishbone.adr[14:30] == 0x000c) & (self.real_hcca != 0), ## in our DMA range
|
||||
self.wr_fifo.we.eq(1),
|
||||
self.wr_fifo.din.eq(Cat(self.wishbone.adr[0:14], self.real_hcca[16:32], self.wishbone.dat_w[30:62]))
|
||||
),
|
||||
NextState("WriteWait")
|
||||
).Elif(self.wishbone.stb & self.wishbone.cyc & ~self.wishbone.we & self.rd_fifo_addr.writable,
|
||||
If((self.wishbone.adr[14:30] == 0x000c) & (self.real_hcca != 0), ## in our DMA range
|
||||
NextValue(adr, self.wishbone.adr),
|
||||
self.rd_fifo_addr.we.eq(1),
|
||||
self.rd_fifo_addr.din.eq(Cat(self.wishbone.adr[0:14], self.real_hcca[16:32]))
|
||||
),
|
||||
NextState("ReadWait"),
|
||||
)
|
||||
)
|
||||
fsm.act("WriteWait",
|
||||
#SBUS_DATA_OE_LED_2_o.eq(1),
|
||||
If((self.wishbone.adr[14:30] == 0x000c) & (self.real_hcca != 0), ## in our DMA range
|
||||
self.wishbone.ack.eq(1),
|
||||
).Else(
|
||||
self.wishbone.err.eq(1)
|
||||
),
|
||||
If(~self.wishbone.stb,
|
||||
NextState("Idle")
|
||||
)
|
||||
)
|
||||
fsm.act("ReadWait",
|
||||
#SBUS_DATA_OE_LED_2_o.eq(1),
|
||||
If((adr[14:30] == 0x000c) & (self.real_hcca != 0), ## in our DMA range
|
||||
If(self.rd_fifo_data.readable,
|
||||
self.wishbone.ack.eq(1),
|
||||
self.rd_fifo_data.re.eq(1),
|
||||
NextValue(data, self.rd_fifo_data.dout),
|
||||
self.wishbone.dat_r.eq(self.rd_fifo_data.dout),
|
||||
NextState("ReadWait2")
|
||||
)
|
||||
).Else(
|
||||
self.wishbone.err.eq(1),
|
||||
If(~self.wishbone.stb,
|
||||
NextState("Idle")
|
||||
)
|
||||
)
|
||||
)
|
||||
fsm.act("ReadWait2",
|
||||
#SBUS_DATA_OE_LED_2_o.eq(1),
|
||||
self.wishbone.ack.eq(1),
|
||||
self.wishbone.dat_r.eq(data),
|
||||
If(~self.wishbone.stb,
|
||||
NextState("Idle")
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user