bfm: dma_skeleton
authorFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 13 Dec 2014 00:18:08 +0000 (01:18 +0100)
committerFlorent Kermarrec <florent@enjoy-digital.fr>
Sat, 13 Dec 2014 00:18:08 +0000 (01:18 +0100)
lib/sata/command/__init__.py
lib/sata/test/bfm.py
lib/sata/test/command_tb.py
lib/sata/transport/__init__.py

index c053eb056019e761c9644119fc8cdaa6098d7b97..c68b8beacce8bf4b9e5a8fb4ea6e7687f6176b0c 100644 (file)
@@ -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),
                        )
                ]
 
index d6b4f4a0b5a2e3cb8eff6106ec7260ebefa61976..435ac2b4c335a1c878fc0669ab7fbbcb394f378b 100644 (file)
@@ -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,
index 2ecbeef2c341ba45e604549cb7e3e007d489ffc3..636d27f75c9be4d8c183fa9da8e0b2529dcd34ac 100644 (file)
@@ -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)
index 703f90786a206cf0d101ecac260240e8593971a7..26570f6e56dd754c27730b7f20b1ae48f6050857 100644 (file)
@@ -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):