add mode generic CommandGenerator for debug

This commit is contained in:
Florent Kermarrec 2014-12-20 16:06:02 +01:00
parent 9dc6903c55
commit eebc2abcda
3 changed files with 157 additions and 77 deletions

View File

@ -152,38 +152,116 @@ class ClockLeds(Module):
sata_tx_cnt.eq(sata_tx_cnt-1) sata_tx_cnt.eq(sata_tx_cnt-1)
) )
class IdentifyRequester(Module, AutoCSR): class CommandGenerator(Module, AutoCSR):
def __init__(self, sata_con): def __init__(self, sata_con, sector_size):
self._req = CSRStorage() self._write = CSR()
req = self._req.storage self._read = CSR()
self._identify = CSR()
self._sector = CSRStorage(48)
self._count = CSRStorage(4)
self._data = CSRStorage(32) # Note: fixed data, add a fifo later
req_d = Signal() self._sucess = CSRStatus()
self._failed = CSRStatus()
self.fsm = fsm = FSM(reset_state="IDLE")
def new_command(csr):
return csr.r & csr.re
cnt = Signal(16)
sector = self._sector.storage
count = self._count.storage
data = self._data.storage
success = self._sucess.status
failed = self._failed.status
clr_status = Signal()
set_success = Signal()
set_failed = Signal()
self.sync += [ self.sync += [
req_d.eq(req), If(clr_status,
If(req & ~req_d, success.eq(0),
sata_con.sink.stb.eq(1) failed.eq(0),
).Elif(sata_con.sink.ack, ).Elif(set_success,
sata_con.sink.stb.eq(0) success.eq(1)
).Elif(set_failed,
failed.eq(1)
) )
] ]
self.comb += [ self.comb += sata_con.source.ack.eq(1)
# FSM
fsm.act("IDLE",
clr_status.eq(1),
If(new_command(self._write),
NextState("SEND_WRITE_CMD")
).Elif(new_command(self._read),
NextState("SEND_READ_CMD")
).Elif(new_command(self._identify),
NextState("SEND_IDENTIFY_CMD")
)
)
fsm.act("SEND_WRITE_CMD",
sata_con.sink.stb.eq(1),
sata_con.sink.sop.eq(cnt == 0),
sata_con.sink.eop.eq(cnt == (count*sector_size-1)),
sata_con.sink.write.eq(1),
sata_con.sink.sector.eq(sector),
sata_con.sink.count.eq(count),
sata_con.sink.data.eq(data),
If(sata_con.sink.eop & sata_con.sink.ack,
NextState("WAIT_WRITE_ACK")
)
)
fsm.act("WAIT_WRITE_ACK",
# XXX: add check of success / failed
If(sata_con.source.stb & sata_con.source.eop,
set_success.eq(1),
NextState("IDLE")
)
)
fsm.act("SEND_READ_CMD",
sata_con.sink.stb.eq(1),
sata_con.sink.sop.eq(1),
sata_con.sink.eop.eq(1),
sata_con.sink.read.eq(1),
sata_con.sink.sector.eq(sector),
sata_con.sink.count.eq(count),
If(sata_con.sink.ack,
NextState("WAIT_READ_ACK_AND_DATA")
)
)
fsm.act("WAIT_READ_ACK_AND_DATA",
# XXX: add check of success / failed and receive data
If(sata_con.source.stb & sata_con.source.eop,
set_success.eq(1),
NextState("IDLE")
)
)
fsm.act("SEND_IDENTIFY_CMD",
sata_con.sink.stb.eq(1),
sata_con.sink.sop.eq(1), sata_con.sink.sop.eq(1),
sata_con.sink.eop.eq(1), sata_con.sink.eop.eq(1),
sata_con.sink.identify.eq(1), sata_con.sink.identify.eq(1),
sata_con.sink.sector.eq(0), If(sata_con.sink.ack,
sata_con.sink.count.eq(1), NextState("WAIT_IDENTIFY_ACK_AND_DATA")
sata_con.sink.data.eq(0), )
)
sata_con.sink.ack.eq(1), fsm.act("WAIT_IDENTIFY_ACK_AND_DATA",
] # XXX: add check of success / failed and receive data
If(sata_con.source.stb & sata_con.source.eop,
set_success.eq(1),
NextState("IDLE")
)
)
class TestDesign(UART2WB, AutoCSR): class TestDesign(UART2WB, AutoCSR):
default_platform = "kc705" default_platform = "kc705"
csr_map = { csr_map = {
"mila": 10, "mila": 10,
"identify_requester": 11 "command_generator": 11
} }
csr_map.update(UART2WB.csr_map) csr_map.update(UART2WB.csr_map)
@ -195,7 +273,7 @@ class TestDesign(UART2WB, AutoCSR):
self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, host=True, speed="SATA2") self.sata_phy = SATAPHY(platform.request("sata_host"), clk_freq, host=True, speed="SATA2")
self.sata_con = SATACON(self.sata_phy, sector_size=512, max_count=8) self.sata_con = SATACON(self.sata_phy, sector_size=512, max_count=8)
self.identify_requester = IdentifyRequester(self.sata_con) self.command_generator = CommandGenerator(self.sata_con, sector_size=512)
self.clock_leds = ClockLeds(platform) self.clock_leds = ClockLeds(platform)
@ -226,15 +304,12 @@ class TestDesign(UART2WB, AutoCSR):
self.sata_phy.sink.data, self.sata_phy.sink.data,
self.sata_phy.sink.charisk, self.sata_phy.sink.charisk,
self.sata_phy.datapath.tx.sink.stb,
self.sata_phy.datapath.tx.sink.data,
self.sata_phy.datapath.tx.sink.charisk,
self.sata_phy.datapath.tx.sink.ack,
self.sata_con.sink.stb, self.sata_con.sink.stb,
self.sata_con.sink.sop, self.sata_con.sink.sop,
self.sata_con.sink.eop, self.sata_con.sink.eop,
self.sata_con.sink.ack, self.sata_con.sink.ack,
self.sata_con.sink.write,
self.sata_con.sink.read,
self.sata_con.sink.identify, self.sata_con.sink.identify,
self.sata_con.source.stb, self.sata_con.source.stb,

View File

@ -1,71 +1,31 @@
import time import time
from config import * from config import *
from miscope.host.dump import * from tools import *
from miscope.host.drivers import MiLaDriver from miscope.host.drivers import MiLaDriver
mila = MiLaDriver(wb.regs, "mila", use_rle=False) mila = MiLaDriver(wb.regs, "mila")
wb.open() wb.open()
regs = wb.regs regs = wb.regs
### ###
trigger0 = mila.sata_con_sink_stb_o*1 #trigger0 = mila.sata_phy_source_source_payload_data_o*primitives["R_OK"]
mask0 = mila.sata_con_sink_stb_m #mask0 = mila.sata_phy_source_source_payload_data_m
trigger0 = mila.sata_con_sink_payload_identify_o*1
mask0 = mila.sata_con_sink_payload_identify_m
mila.prog_term(port=0, trigger=trigger0, mask=mask0) mila.prog_term(port=0, trigger=trigger0, mask=mask0)
mila.prog_sum("term") mila.prog_sum("term")
# Trigger / wait / receive # Trigger / wait / receive
mila.trigger(offset=32, length=256) mila.trigger(offset=32, length=512)
regs.identify_requester_req.write(1) regs.command_generator_identify.write(1)
regs.identify_requester_req.write(0)
mila.wait_done() mila.wait_done()
mila.read() mila.read()
mila.export("dump.vcd") mila.export("dump.vcd")
mila.export("dump.csv")
mila.export("dump.py")
### ###
wb.close() wb.close()
### print_link_trace(mila,
tx_data_name="sata_phy_sink_sink_payload_data",
primitives = { rx_data_name="sata_phy_source_source_payload_data"
"ALIGN" : 0x7B4A4ABC, )
"CONT" : 0X9999AA7C,
"SYNC" : 0xB5B5957C,
"R_RDY" : 0x4A4A957C,
"R_OK" : 0x3535B57C,
"R_ERR" : 0x5656B57C,
"R_IP" : 0X5555B57C,
"X_RDY" : 0x5757B57C,
"CONT" : 0x9999AA7C,
"WTRM" : 0x5858B57C,
"SOF" : 0x3737B57C,
"EOF" : 0xD5D5B57C,
"HOLD" : 0xD5D5AA7C,
"HOLDA" : 0X9595AA7C
}
def decode_primitive(dword):
for k, v in primitives.items():
if dword == v:
return k
return ""
dump = Dump()
dump.add_from_layout(mila.layout, mila.dat)
for var in dump.vars:
if var.name == "sata_phy_sink_sink_payload_data":
tx_data = var.values
if var.name == "sata_phy_source_source_payload_data":
rx_data = var.values
for i in range(len(tx_data)):
tx = "%08x " %tx_data[i]
tx += decode_primitive(tx_data[i])
tx += " "*(16-len(tx))
rx = "%08x " %rx_data[i]
rx += decode_primitive(rx_data[i])
rx += " "*(16-len(rx))
print(tx + rx)

45
test/tools.py Normal file
View File

@ -0,0 +1,45 @@
from miscope.host.dump import *
primitives = {
"ALIGN" : 0x7B4A4ABC,
"CONT" : 0X9999AA7C,
"SYNC" : 0xB5B5957C,
"R_RDY" : 0x4A4A957C,
"R_OK" : 0x3535B57C,
"R_ERR" : 0x5656B57C,
"R_IP" : 0X5555B57C,
"X_RDY" : 0x5757B57C,
"CONT" : 0x9999AA7C,
"WTRM" : 0x5858B57C,
"SOF" : 0x3737B57C,
"EOF" : 0xD5D5B57C,
"HOLD" : 0xD5D5AA7C,
"HOLDA" : 0X9595AA7C
}
def decode_primitive(dword):
for k, v in primitives.items():
if dword == v:
return k
return ""
def print_link_trace(mila, tx_data_name, rx_data_name):
dump = Dump()
dump.add_from_layout(mila.layout, mila.dat)
for var in dump.vars:
if var.name == tx_data_name:
tx_data = var.values
if var.name == rx_data_name:
rx_data = var.values
for i in range(len(tx_data)):
tx = "%08x " %tx_data[i]
tx += decode_primitive(tx_data[i])
tx += " "*(16-len(tx))
rx = "%08x " %rx_data[i]
rx += decode_primitive(rx_data[i])
rx += " "*(16-len(rx))
print(tx + rx)