mirror of
https://github.com/rdolbeau/NuBusFPGA.git
synced 2024-06-29 05:29:32 +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
|
from litex.soc.interconnect import wishbone
|
||||||
|
|
||||||
class NuBus(Module):
|
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)
|
self.add_sources(platform)
|
||||||
|
|
||||||
#led0 = platform.request("user_led", 0)
|
#led0 = platform.request("user_led", 0)
|
||||||
|
@ -18,11 +22,11 @@ class NuBus(Module):
|
||||||
# slave
|
# slave
|
||||||
tmo_oe = Signal() # output enable
|
tmo_oe = Signal() # output enable
|
||||||
tm0_i_n = Signal()
|
tm0_i_n = Signal()
|
||||||
tm0_o_n = Signal()
|
tm0_o_n = Signal(reset = 1)
|
||||||
tm1_i_n = Signal()
|
tm1_i_n = Signal()
|
||||||
tm1_o_n = Signal()
|
tm1_o_n = Signal(reset = 1)
|
||||||
ack_i_n = Signal()
|
ack_i_n = Signal()
|
||||||
ack_o_n = Signal()
|
ack_o_n = Signal(reset = 1)
|
||||||
|
|
||||||
ad_oe = Signal()
|
ad_oe = Signal()
|
||||||
ad_i_n = Signal(32)
|
ad_i_n = Signal(32)
|
||||||
|
@ -31,12 +35,12 @@ class NuBus(Module):
|
||||||
id_i_n = Signal(4)
|
id_i_n = Signal(4)
|
||||||
|
|
||||||
start_i_n = Signal()
|
start_i_n = Signal()
|
||||||
start_o_n = Signal() # master via master_oe
|
start_o_n = Signal(reset = 1) # master via master_oe
|
||||||
|
|
||||||
# master
|
# master
|
||||||
rqst_oe = Signal()
|
rqst_oe = Signal()
|
||||||
rqst_i_n = 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
|
# sampled signals, exposing the value of the register acquired on the falling edge
|
||||||
# they can change every cycle *on falling edge*
|
# they can change every cycle *on falling edge*
|
||||||
|
@ -46,6 +50,7 @@ class NuBus(Module):
|
||||||
sampled_start = Signal()
|
sampled_start = Signal()
|
||||||
sampled_ack = Signal()
|
sampled_ack = Signal()
|
||||||
sampled_ad = Signal(32)
|
sampled_ad = Signal(32)
|
||||||
|
sampled_ad_byterev = Signal(32)
|
||||||
|
|
||||||
# master
|
# master
|
||||||
sampled_rqst = Signal()
|
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_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[0:28].eq(sampled_ad[0:28]),
|
||||||
processed_super_ad[28:32].eq(Signal(4, reset = 0x8)),
|
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
|
# 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"))
|
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",
|
dma_fsm.act("Reset",
|
||||||
NextState("Idle")
|
NextState("Idle")
|
||||||
)
|
)
|
||||||
dma_fsm.act("Idle",
|
dma_fsm.act("Idle",
|
||||||
If(wb_dma.cyc & wb_dma.stb & ~sampled_rqst, # we need the bus and it's not being requested
|
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
|
If(owning_bus, # we own the bus, skip arbitration
|
||||||
NextState("AdrCycle"),
|
NextState("AdrCycle"),
|
||||||
).Else( # go for arbitration
|
).Else( # go for arbitration
|
||||||
NextState("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",
|
dma_fsm.act("Arbitration",
|
||||||
|
@ -256,7 +308,11 @@ class NuBus(Module):
|
||||||
rqst_o_n.eq(0),
|
rqst_o_n.eq(0),
|
||||||
If(grant & ~decoded_busy, # I'm now 'owner'
|
If(grant & ~decoded_busy, # I'm now 'owner'
|
||||||
NextValue(owning_bus, 1),
|
NextValue(owning_bus, 1),
|
||||||
|
If(burst,
|
||||||
|
NextState("Burst4AdrCycle"),
|
||||||
|
).Else(
|
||||||
NextState("AdrCycle"),
|
NextState("AdrCycle"),
|
||||||
|
),
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
dma_fsm.act("AdrCycle",
|
dma_fsm.act("AdrCycle",
|
||||||
|
@ -308,6 +364,110 @@ class NuBus(Module):
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
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
|
# stuff at this end so we don't use the signals inadvertantly
|
||||||
|
|
||||||
# real NuBus signals
|
# real NuBus signals
|
||||||
|
|
Loading…
Reference in New Issue
Block a user