From eb226c1adef12aeb9ccb2edc412179464b80af5e Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sat, 13 Dec 2014 01:18:08 +0100 Subject: [PATCH] bfm: dma_skeleton --- lib/sata/command/__init__.py | 7 ++++++ lib/sata/test/bfm.py | 41 ++++++++++++++++++++++++++++++++-- lib/sata/test/command_tb.py | 26 +++++++++++++++++++-- lib/sata/transport/__init__.py | 16 ++++++------- 4 files changed, 78 insertions(+), 12 deletions(-) diff --git a/lib/sata/command/__init__.py b/lib/sata/command/__init__.py index c053eb05..c68b8bea 100644 --- a/lib/sata/command/__init__.py +++ b/lib/sata/command/__init__.py @@ -110,8 +110,15 @@ class SATACommandRX(Module): self.comb += [ transport.source.ack.eq(1), + # XXX for test If(transport.source.stb & (transport.source.type == fis_types["DMA_ACTIVATE_D2H"]), self.to_tx.dma_activate.eq(1) + ), + If(transport.source.stb & (transport.source.type == fis_types["DATA"]), + source.stb.eq(1), + source.sop.eq(transport.source.sop), + source.eop.eq(transport.source.eop), + source.data.eq(transport.source.data), ) ] diff --git a/lib/sata/test/bfm.py b/lib/sata/test/bfm.py index d6b4f4a0..435ac2b4 100644 --- a/lib/sata/test/bfm.py +++ b/lib/sata/test/bfm.py @@ -385,13 +385,50 @@ class CommandLayer(Module): self.debug = debug self.transport.set_command_callback(self.callback) + self.dma_enable = 0 + self.dma_address = 0 + + def allocate_dma(self, base, length): + self.dma_base = base + self.dma_buffer = [0]*(length//4) + + def enable_dma(self): + self.dma_enable = 1 + + def disable_dma(self): + self.dma_enable = 0 + + def dma_write(self, adr, data): + current_adr = (adr-self.dma_base)//4 + for i in range(len(data)): + self.dma_buffer[current_adr+i] = data[i] + + def dma_read(self, adr, length=1): + current_adr = (adr-self.dma_base)//4 + data = [] + for i in range(length//4): + data.append(self.dma_buffer[current_adr+i]) + return data + def callback(self, fis): + # XXX maximum of 2048 DWORDS per DMA if isinstance(fis, FIS_REG_H2D): if fis.command == regs["WRITE_DMA_EXT"]: - # XXX add checks + self.dma_address = fis.lba_lsb dma_activate = FIS_DMA_ACTIVATE_D2H() - # XXX fill dma_activate self.transport.send(dma_activate) + elif fis.command == regs["READ_DMA_EXT"]: + self.dma_address = fis.lba_lsb + data = FIS_DATA(self.dma_read(fis.lba_lsb, fis.count*4)) + self.transport.send(data) + elif fis.command == regs["IDENTIFY_DEVICE_DMA"]: + self.dma_address = fis.lba_lsb + data = FIS_DATA(self.dma_read(fis.lba_lsb, fis.count*4)) + self.transport.send(data) + elif isinstance(fis, FIS_DATA): + if self.dma_enable: + self.dma_write(self.dma_address, fis.packet[1:]) + self.dma_address += len(fis.packet[1:]) class BFM(Module): def __init__(self, diff --git a/lib/sata/test/command_tb.py b/lib/sata/test/command_tb.py index 2ecbeef2..636d27f7 100644 --- a/lib/sata/test/command_tb.py +++ b/lib/sata/test/command_tb.py @@ -21,6 +21,8 @@ class TB(Module): self.submodules.command = SATACommand(self.transport) def gen_simulation(self, selfp): + self.bfm.command.allocate_dma(0x00000000, 64*1024*1024) + self.bfm.command.enable_dma() for i in range(100): yield for i in range(32): @@ -28,13 +30,33 @@ class TB(Module): selfp.command.sink.sop = (i==0) selfp.command.sink.eop = (i==31) selfp.command.sink.write = 1 - selfp.command.sink.address = 0x1234 + selfp.command.sink.address = 1024 selfp.command.sink.length = 32 selfp.command.sink.data = i yield while selfp.command.sink.ack == 0: yield - selfp.command.sink.ack = 0 + selfp.command.sink.stb = 0 + for i in range(32): + yield + selfp.command.sink.stb = 1 + selfp.command.sink.sop = 1 + selfp.command.sink.eop = 1 + selfp.command.sink.write = 0 + selfp.command.sink.read = 1 + selfp.command.sink.address = 1024 + selfp.command.sink.length = 32 + yield + while selfp.command.sink.ack == 0: + yield + selfp.command.sink.stb = 0 + while True: + if selfp.command.source.stb: + print("%08x" %selfp.command.source.data) + yield + #dma_dump = self.bfm.command.dma_read(1024, 32*4) + #for d in dma_dump: + # print("%08x" %d) if __name__ == "__main__": run_simulation(TB(), ncycles=512, vcd_name="my.vcd", keep_files=True) diff --git a/lib/sata/transport/__init__.py b/lib/sata/transport/__init__.py index 703f9078..26570f6e 100644 --- a/lib/sata/transport/__init__.py +++ b/lib/sata/transport/__init__.py @@ -60,7 +60,7 @@ class SATATransportTX(Module): ) fsm.act("SEND_REG_H2D_CMD", _encode_cmd(sink, fis_reg_h2d_layout, encoded_cmd), - cmd_len.eq(fis_reg_h2d_cmd_len), + cmd_len.eq(fis_reg_h2d_cmd_len-1), cmd_send.eq(1), If(cmd_done, sink.ack.eq(1), @@ -69,7 +69,7 @@ class SATATransportTX(Module): ) fsm.act("SEND_DATA_CMD", _encode_cmd(sink, fis_data_layout, encoded_cmd), - cmd_len.eq(fis_data_cmd_len), + cmd_len.eq(fis_data_cmd_len-1), cmd_with_data.eq(1), cmd_send.eq(1), If(cmd_done, @@ -84,7 +84,6 @@ class SATATransportTX(Module): ) ) - cmd_cases = {} for i in range(cmd_ndwords): cmd_cases[i] = [link.sink.d.eq(encoded_cmd[32*i:32*(i+1)])] @@ -96,7 +95,7 @@ class SATATransportTX(Module): link.sink.eop.eq((cnt==cmd_len) & ~cmd_with_data), Case(cnt, cmd_cases), inc_cnt.eq(link.sink.ack), - cmd_done.eq(cnt==cmd_len) + cmd_done.eq((cnt==cmd_len) & link.sink.ack) ).Elif(data_send, link.sink.stb.eq(sink.stb), link.sink.sop.eq(0), @@ -152,6 +151,7 @@ class SATATransportRX(Module): self.submodules += fsm fsm.act("IDLE", + clr_cnt.eq(1), If(link.source.stb & link.source.sop, If(test_type("REG_D2H"), NextState("RECEIVE_REG_D2H_CMD") @@ -168,7 +168,7 @@ class SATATransportRX(Module): ) ) fsm.act("RECEIVE_REG_D2H_CMD", - cmd_len.eq(fis_reg_d2h_cmd_len), + cmd_len.eq(fis_reg_d2h_cmd_len-1), cmd_receive.eq(1), If(cmd_done, NextState("PRESENT_REG_D2H_CMD") @@ -182,7 +182,7 @@ class SATATransportRX(Module): ) ) fsm.act("RECEIVE_DMA_ACTIVATE_D2H_CMD", - cmd_len.eq(fis_dma_activate_d2h_cmd_len), + cmd_len.eq(fis_dma_activate_d2h_cmd_len-1), cmd_receive.eq(1), If(cmd_done, NextState("PRESENT_DMA_ACTIVATE_D2H_CMD") @@ -196,7 +196,7 @@ class SATATransportRX(Module): ) ) fsm.act("RECEIVE_DATA_CMD", - cmd_len.eq(fis_data_cmd_len), + cmd_len.eq(fis_data_cmd_len-1), cmd_receive.eq(1), If(cmd_done, NextState("PRESENT_DATA") @@ -236,7 +236,7 @@ class SATATransportRX(Module): ).Elif(inc_cnt, cnt.eq(cnt+1) ) - self.comb += cmd_done.eq(cnt==cmd_len) + self.comb += cmd_done.eq((cnt==cmd_len) & link.source.ack) self.comb += link.source.ack.eq(cmd_receive | (data_receive & source.ack)) class SATATransport(Module): -- 2.30.2