mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2025-03-12 00:33:08 +00:00
sync non-sampling with sampling code
This commit is contained in:
parent
45de956195
commit
b935541f61
@ -7,8 +7,12 @@ import litex
|
||||
from litex.soc.interconnect import wishbone
|
||||
|
||||
class NuBus(Module):
|
||||
def __init__(self, platform, wb_read, wb_write, wb_dma, cd_nubus="nubus", cd_nubus90="nubus90"):
|
||||
|
||||
def __init__(self, soc,
|
||||
burst_size, tosbus_fifo, fromsbus_fifo, fromsbus_req_fifo,
|
||||
wb_read, wb_write, wb_dma,
|
||||
cd_nubus="nubus", cd_nubus90="nubus90"):
|
||||
|
||||
platform = soc.platform
|
||||
self.add_sources(platform)
|
||||
|
||||
#led0 = platform.request("user_led", 0)
|
||||
@ -18,11 +22,11 @@ class NuBus(Module):
|
||||
# slave
|
||||
tmo_oe = Signal() # output enable
|
||||
tm0_i_n = Signal()
|
||||
tm0_o_n = Signal()
|
||||
tm0_o_n = Signal(reset = 1)
|
||||
tm1_i_n = Signal()
|
||||
tm1_o_n = Signal()
|
||||
tm1_o_n = Signal(reset = 1)
|
||||
ack_i_n = Signal()
|
||||
ack_o_n = Signal()
|
||||
ack_o_n = Signal(reset = 1)
|
||||
|
||||
ad_oe = Signal()
|
||||
ad_i_n = Signal(32)
|
||||
@ -31,12 +35,12 @@ class NuBus(Module):
|
||||
id_i_n = Signal(4)
|
||||
|
||||
start_i_n = Signal()
|
||||
start_o_n = Signal() # master via master_oe
|
||||
start_o_n = Signal(reset = 1) # master via master_oe
|
||||
|
||||
# master
|
||||
rqst_oe = Signal()
|
||||
rqst_i_n = Signal()
|
||||
rqst_o_n = Signal()
|
||||
rqst_o_n = Signal(reset = 1)
|
||||
|
||||
# sampled signals, exposing the value of the register acquired on the falling edge
|
||||
# they can change every cycle *on falling edge*
|
||||
@ -46,6 +50,7 @@ class NuBus(Module):
|
||||
sampled_start = Signal()
|
||||
sampled_ack = Signal()
|
||||
sampled_ad = Signal(32)
|
||||
sampled_ad_byterev = Signal(32)
|
||||
|
||||
# master
|
||||
sampled_rqst = Signal()
|
||||
@ -62,6 +67,10 @@ class NuBus(Module):
|
||||
processed_ad[23:32].eq(Cat(sampled_ad[23], Signal(8, reset = 0xf0)))), # 24 bits, a.k.a 22 bits of words
|
||||
processed_super_ad[0:28].eq(sampled_ad[0:28]),
|
||||
processed_super_ad[28:32].eq(Signal(4, reset = 0x8)),
|
||||
sampled_ad_byterev[ 0: 8].eq(sampled_ad[24:32]),
|
||||
sampled_ad_byterev[ 8:16].eq(sampled_ad[16:24]),
|
||||
sampled_ad_byterev[16:24].eq(sampled_ad[ 8:16]),
|
||||
sampled_ad_byterev[24:32].eq(sampled_ad[ 0: 8]),
|
||||
]
|
||||
|
||||
# decoded signals, exposing decoded results from the sampled signals
|
||||
@ -232,16 +241,59 @@ class NuBus(Module):
|
||||
]
|
||||
|
||||
self.submodules.dma_fsm = dma_fsm = ClockDomainsRenamer(cd_nubus)(FSM(reset_state="Reset"))
|
||||
ctr = Signal(2) # burst counter
|
||||
burst = Signal()
|
||||
burst_we = Signal()
|
||||
|
||||
data_width = burst_size * 4
|
||||
data_width_bits = burst_size * 32
|
||||
blk_addr_width = 32 - log2_int(data_width) # 27 for burst_size == 8, 28 for burst_size == 4
|
||||
fifo_addr = Signal(blk_addr_width)
|
||||
fifo_blk_addr = Signal(blk_addr_width)
|
||||
fifo_buffer = Signal(data_width_bits)
|
||||
|
||||
tosbus_fifo_dout = Record(soc.tosbus_layout)
|
||||
self.comb += tosbus_fifo_dout.raw_bits().eq(tosbus_fifo.dout)
|
||||
tosbus_fifo_dout_data_byterev = Signal(data_width_bits)
|
||||
tosbus_fifo_dout_bytereversal_stmts = [ tosbus_fifo_dout_data_byterev[k*32+j*8:k*32+j*8+8].eq(tosbus_fifo_dout.data[k*32+32-j*8-8:k*32+32-j*8]) for k in range(burst_size) for j in range(4) ]
|
||||
self.comb += tosbus_fifo_dout_bytereversal_stmts
|
||||
|
||||
fromsbus_req_fifo_dout = Record(soc.fromsbus_req_layout)
|
||||
self.comb += fromsbus_req_fifo_dout.raw_bits().eq(fromsbus_req_fifo.dout)
|
||||
|
||||
fromsbus_fifo_din = Record(soc.fromsbus_layout)
|
||||
self.comb += fromsbus_fifo.din.eq(fromsbus_fifo_din.raw_bits())
|
||||
|
||||
dma_fsm.act("Reset",
|
||||
NextState("Idle")
|
||||
)
|
||||
dma_fsm.act("Idle",
|
||||
If(wb_dma.cyc & wb_dma.stb & ~sampled_rqst, # we need the bus and it's not being requested
|
||||
NextValue(burst, 0),
|
||||
If(owning_bus, # we own the bus, skip arbitration
|
||||
NextState("AdrCycle"),
|
||||
).Else( # go for arbitration
|
||||
NextState("Arbitration"),
|
||||
),
|
||||
).Elif(tosbus_fifo.readable & ~sampled_rqst,
|
||||
NextValue(burst, 1),
|
||||
NextValue(burst_we, 1),
|
||||
NextValue(fifo_addr, tosbus_fifo_dout.address[(32-blk_addr_width):32]),
|
||||
If(owning_bus, # we own the bus, skip arbitration
|
||||
NextState("Burst4AdrCycle"),
|
||||
).Else( # go for arbitration
|
||||
NextState("Arbitration"),
|
||||
)
|
||||
).Elif(fromsbus_req_fifo.readable & fromsbus_fifo.writable & ~sampled_rqst,
|
||||
NextValue(burst, 1),
|
||||
NextValue(burst_we, 0),
|
||||
NextValue(fifo_addr, fromsbus_req_fifo_dout.dmaaddress[(32-blk_addr_width):32]),
|
||||
NextValue(fifo_blk_addr, fromsbus_req_fifo_dout.blkaddress),
|
||||
If(owning_bus, # we own the bus, skip arbitration
|
||||
NextState("Burst4AdrCycle"),
|
||||
).Else( # go for arbitration
|
||||
NextState("Arbitration"),
|
||||
)
|
||||
)
|
||||
)
|
||||
dma_fsm.act("Arbitration",
|
||||
@ -256,7 +308,11 @@ class NuBus(Module):
|
||||
rqst_o_n.eq(0),
|
||||
If(grant & ~decoded_busy, # I'm now 'owner'
|
||||
NextValue(owning_bus, 1),
|
||||
NextState("AdrCycle"),
|
||||
If(burst,
|
||||
NextState("Burst4AdrCycle"),
|
||||
).Else(
|
||||
NextState("AdrCycle"),
|
||||
),
|
||||
)
|
||||
)
|
||||
dma_fsm.act("AdrCycle",
|
||||
@ -307,6 +363,110 @@ class NuBus(Module):
|
||||
NextState("FinishCycle"),
|
||||
)
|
||||
)
|
||||
|
||||
dma_fsm.act("Burst4AdrCycle",
|
||||
start_arbitration.eq(0),
|
||||
master_oe.eq(1), # for start
|
||||
tmo_oe.eq(1), # for tm0, tm1, ack
|
||||
ad_oe.eq(1), # for write address
|
||||
start_o_n.eq(0),
|
||||
tm0_o_n.eq(1), # burst
|
||||
tm1_o_n.eq(~burst_we),
|
||||
ad_o_n[0].eq(1), # burst
|
||||
ad_o_n[1].eq(0), # burst
|
||||
ad_o_n[2].eq(0), # burst == 4
|
||||
ad_o_n[3].eq(1), # burst == 4
|
||||
ad_o_n[4:32].eq(~fifo_addr),
|
||||
ack_o_n.eq(1),
|
||||
NextValue(ctr, 0),
|
||||
If(burst_we,
|
||||
NextState("Burst4DatCycleTM0"),
|
||||
).Else(
|
||||
NextState("Burst4ReadWaitForTM0"),
|
||||
)
|
||||
)
|
||||
dma_fsm.act("Burst4ReadWaitForTM0",
|
||||
master_oe.eq(1), # for start
|
||||
start_o_n.eq(1), # start finished, but still need to be driven
|
||||
If(sampled_ack, # oups
|
||||
fromsbus_req_fifo.re.eq(1), # remove request to avoid infinite repeat
|
||||
#NextValue(led0, 1),
|
||||
#NextValue(led1, 1),
|
||||
NextState("FinishCycle"),
|
||||
).Elif(sampled_tm0,
|
||||
Case(ctr, {
|
||||
#0x0: NextValue(fifo_buffer[ 0: 32], sampled_ad),
|
||||
#0x1: NextValue(fifo_buffer[32: 64], sampled_ad),
|
||||
#0x2: NextValue(fifo_buffer[64: 96], sampled_ad),
|
||||
##0x3: NextValue(fifo_buffer[96:128], sampled_ad),
|
||||
0x0: NextValue(fifo_buffer[ 0: 32], sampled_ad_byterev),
|
||||
0x1: NextValue(fifo_buffer[32: 64], sampled_ad_byterev),
|
||||
0x2: NextValue(fifo_buffer[64: 96], sampled_ad_byterev),
|
||||
#0x3: NextValue(fifo_buffer[96:128], sampled_ad_byterev),
|
||||
}),
|
||||
NextValue(ctr, ctr + 1),
|
||||
If(ctr == 0x2, # burst next-to-last
|
||||
NextState("Burst4ReadWaitForAck"),
|
||||
).Else(
|
||||
NextState("Burst4ReadWaitForTM0"),
|
||||
)
|
||||
)
|
||||
)
|
||||
dma_fsm.act("Burst4ReadWaitForAck",
|
||||
master_oe.eq(1), # for start
|
||||
start_o_n.eq(1), # start finished, but still need to be driven
|
||||
If(sampled_ack,
|
||||
fromsbus_req_fifo.re.eq(1), # remove request
|
||||
fromsbus_fifo.we.eq(1),
|
||||
fromsbus_fifo_din.blkaddress.eq(fifo_blk_addr),
|
||||
#fromsbus_fifo_din.data.eq(Cat(fifo_buffer[0:96], sampled_ad)), # we use sampled_ad directly for 96:128
|
||||
fromsbus_fifo_din.data.eq(Cat(fifo_buffer[0:96], sampled_ad_byterev)), # we use sampled_ad directly for 96:128
|
||||
# fixme: check status ??? (tm0 and tm1 should be active for no-error)
|
||||
#NextValue(led0, (~sampled_tm0 | ~sampled_tm1)),
|
||||
NextState("FinishCycle"),
|
||||
)
|
||||
)
|
||||
dma_fsm.act("Burst4DatCycleTM0",
|
||||
master_oe.eq(1), # for start
|
||||
ad_oe.eq(1), # for write data
|
||||
start_o_n.eq(1), # start finished, but still need to be driven
|
||||
Case(ctr, {
|
||||
#0x0: ad_o_n.eq(~tosbus_fifo_dout.data[ 0: 32]),
|
||||
#0x1: ad_o_n.eq(~tosbus_fifo_dout.data[32: 64]),
|
||||
#0x2: ad_o_n.eq(~tosbus_fifo_dout.data[64: 96]),
|
||||
##0x3: ad_o_n.eq(~tosbus_fifo_dout.data[96:128]),
|
||||
0x0: ad_o_n.eq(~tosbus_fifo_dout_data_byterev[ 0: 32]),
|
||||
0x1: ad_o_n.eq(~tosbus_fifo_dout_data_byterev[32: 64]),
|
||||
0x2: ad_o_n.eq(~tosbus_fifo_dout_data_byterev[64: 96]),
|
||||
#0x3: ad_o_n.eq(~tosbus_fifo_dout_data_byterev[96:128]),
|
||||
}),
|
||||
If(sampled_ack, # oups
|
||||
#NextValue(led0, 1),
|
||||
#NextValue(led1, 1),
|
||||
tosbus_fifo.re.eq(1), # remove FIFO entry to avoid infinite repeat
|
||||
NextState("FinishCycle"),
|
||||
).Elif(sampled_tm0,
|
||||
NextValue(ctr, ctr + 1),
|
||||
If(ctr == 0x2, # burst next-to-last
|
||||
NextState("Burst4DatCycleAck"),
|
||||
).Else(
|
||||
NextState("Burst4DatCycleTM0"),
|
||||
)
|
||||
)
|
||||
)
|
||||
dma_fsm.act("Burst4DatCycleAck",
|
||||
master_oe.eq(1), # for start
|
||||
ad_oe.eq(1), # for write data
|
||||
start_o_n.eq(1), # start finished, but still need to be driven
|
||||
#ad_o_n.eq(~tosbus_fifo_dout.data[96:128]), # last word
|
||||
ad_o_n.eq(~tosbus_fifo_dout_data_byterev[96:128]), # last word
|
||||
If(sampled_ack,
|
||||
tosbus_fifo.re.eq(1), # remove FIFO entry at last
|
||||
# fixme: check status ??? (tm0 and tm1 should be active for no-error)
|
||||
#NextValue(led0, (~sampled_tm0 | ~sampled_tm1)),
|
||||
NextState("FinishCycle"),
|
||||
)
|
||||
)
|
||||
|
||||
# stuff at this end so we don't use the signals inadvertantly
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user