rename milkymist-ng to MiSoC
authorSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 9 Nov 2013 14:27:32 +0000 (15:27 +0100)
committerSebastien Bourdeauducq <sebastien@milkymist.org>
Sat, 9 Nov 2013 14:27:32 +0000 (15:27 +0100)
103 files changed:
.gitignore
LICENSE
README
make.py
milkymist/__init__.py [deleted file]
milkymist/counteradc/__init__.py [deleted file]
milkymist/cpuif.py [deleted file]
milkymist/dfii/__init__.py [deleted file]
milkymist/dvisampler/__init__.py [deleted file]
milkymist/dvisampler/analysis.py [deleted file]
milkymist/dvisampler/chansync.py [deleted file]
milkymist/dvisampler/charsync.py [deleted file]
milkymist/dvisampler/clocking.py [deleted file]
milkymist/dvisampler/common.py [deleted file]
milkymist/dvisampler/datacapture.py [deleted file]
milkymist/dvisampler/debug.py [deleted file]
milkymist/dvisampler/decoding.py [deleted file]
milkymist/dvisampler/dma.py [deleted file]
milkymist/dvisampler/edid.py [deleted file]
milkymist/dvisampler/wer.py [deleted file]
milkymist/framebuffer/__init__.py [deleted file]
milkymist/framebuffer/dvi.py [deleted file]
milkymist/framebuffer/format.py [deleted file]
milkymist/framebuffer/phy.py [deleted file]
milkymist/gpio/__init__.py [deleted file]
milkymist/identifier/__init__.py [deleted file]
milkymist/lasmicon/__init__.py [deleted file]
milkymist/lasmicon/bankmachine.py [deleted file]
milkymist/lasmicon/multiplexer.py [deleted file]
milkymist/lasmicon/perf.py [deleted file]
milkymist/lasmicon/refresher.py [deleted file]
milkymist/lm32/__init__.py [deleted file]
milkymist/memtest/__init__.py [deleted file]
milkymist/minimac3/__init__.py [deleted file]
milkymist/mxcrg/__init__.py [deleted file]
milkymist/norflash/__init__.py [deleted file]
milkymist/s6ddrphy/__init__.py [deleted file]
milkymist/s6ddrphy/initsequence.py [deleted file]
milkymist/timer/__init__.py [deleted file]
milkymist/uart/__init__.py [deleted file]
misoclib/__init__.py [new file with mode: 0644]
misoclib/counteradc/__init__.py [new file with mode: 0644]
misoclib/cpuif.py [new file with mode: 0644]
misoclib/dfii/__init__.py [new file with mode: 0644]
misoclib/dvisampler/__init__.py [new file with mode: 0644]
misoclib/dvisampler/analysis.py [new file with mode: 0644]
misoclib/dvisampler/chansync.py [new file with mode: 0644]
misoclib/dvisampler/charsync.py [new file with mode: 0644]
misoclib/dvisampler/clocking.py [new file with mode: 0644]
misoclib/dvisampler/common.py [new file with mode: 0644]
misoclib/dvisampler/datacapture.py [new file with mode: 0644]
misoclib/dvisampler/debug.py [new file with mode: 0644]
misoclib/dvisampler/decoding.py [new file with mode: 0644]
misoclib/dvisampler/dma.py [new file with mode: 0644]
misoclib/dvisampler/edid.py [new file with mode: 0644]
misoclib/dvisampler/wer.py [new file with mode: 0644]
misoclib/framebuffer/__init__.py [new file with mode: 0644]
misoclib/framebuffer/dvi.py [new file with mode: 0644]
misoclib/framebuffer/format.py [new file with mode: 0644]
misoclib/framebuffer/phy.py [new file with mode: 0644]
misoclib/gpio/__init__.py [new file with mode: 0644]
misoclib/identifier/__init__.py [new file with mode: 0644]
misoclib/lasmicon/__init__.py [new file with mode: 0644]
misoclib/lasmicon/bankmachine.py [new file with mode: 0644]
misoclib/lasmicon/multiplexer.py [new file with mode: 0644]
misoclib/lasmicon/perf.py [new file with mode: 0644]
misoclib/lasmicon/refresher.py [new file with mode: 0644]
misoclib/lm32/__init__.py [new file with mode: 0644]
misoclib/memtest/__init__.py [new file with mode: 0644]
misoclib/minimac3/__init__.py [new file with mode: 0644]
misoclib/mxcrg/__init__.py [new file with mode: 0644]
misoclib/norflash/__init__.py [new file with mode: 0644]
misoclib/s6ddrphy/__init__.py [new file with mode: 0644]
misoclib/s6ddrphy/initsequence.py [new file with mode: 0644]
misoclib/timer/__init__.py [new file with mode: 0644]
misoclib/uart/__init__.py [new file with mode: 0644]
software/bios/Makefile
software/bios/main.c
software/common.mak
software/include/base/stdlib.h
software/include/base/string.h
software/libbase/Makefile
software/libbase/id.c
software/libbase/libc.c
software/libbase/vsnprintf.c
software/libcompiler-rt/Makefile
software/libnet/Makefile
software/memtest/Makefile
software/videomixer/Makefile
tb/dvisampler/chansync.py
tb/framebuffer/framebuffer.py
tb/lasmicon/bankmachine.py
tb/lasmicon/common.py
tb/lasmicon/lasmicon.py
tb/lasmicon/lasmicon_df.py
tb/lasmicon/lasmicon_wb.py
tb/lasmicon/refresher.py
tools/Makefile
tools/byteswap.c
tools/flterm.c
tools/mkmmimg.c [deleted file]
tools/mkmscimg.c [new file with mode: 0644]
top.py

index 61fe22b23989bc4c0698c995f4de29bbe9743512..cea03fad14d071f798a8fd18d7d3ac1332ae98b4 100644 (file)
@@ -6,9 +6,8 @@ build/*
 *.elf
 *.bin
 *.fbi
-tools/bin2hex
 tools/flterm
-tools/mkmmimg
+tools/mkmscimg
 tools/byteswap
 software/include/hw/csr.h
 software/include/hw/sdram_phy.h
diff --git a/LICENSE b/LICENSE
index 541a9dcddff8ab19cec64349440243879068d5b5..70a79f87d41fb67282aa134d3dae195f5c514d3c 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Unless otherwise noted, milkymist-ng is copyright (C) 2011-2013 Sebastien Bourdeauducq.
+Unless otherwise noted, MiSoC is copyright (C) 2011-2013 Sebastien Bourdeauducq.
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without modification,
diff --git a/README b/README
index 70d4d25e4479450620cbf79d5069fef4afaa2477..7c49085ad5b43a3ec2dbf0a3c9c5bfbce0a0fcce 100644 (file)
--- a/README
+++ b/README
@@ -1,17 +1,10 @@
-[> Milkymist-ng system-on-chip
+[> MiSoC system-on-chip
 ------------------------------
 
-This is the next-generation Milkymist(tm) system-on-chip design,
-introducing two key features:
- * Built on the powerful Migen VLSI logic design system.
- * Increased system memory performance thanks to LASMI.
+A high performance system-on-chip design based on Migen.
 
-This translates to more development productivity, better video resolution
-and quality, ease of designing complex hardware accelerators, and much
-more flexibility in hardware designs.
-
-The milkymist-ng SoC supports the Mixxeo and the Milkymist One.
-Obtain yours at http://milkymist.org
+MiSoC supports the Mixxeo and the Milkymist One.
+Obtain your development system at http://milkymist.org
 
 [> Instructions (software)
 --------------------------
@@ -53,28 +46,29 @@ Once this is done, build the bitstream with:
 This will generate the build/soc-<platform>.bit programming file
 and load it with UrJTAG.
 
-A new BIOS needs to be built and flashed for the -ng SoC.
+A new BIOS needs to be built and flashed for MiSoC.
+There is no compatibility with Milkymist SoC.
 
 Enjoy!
 
 [> Misc
 -------
 Code repository:
-  https://github.com/milkymist/milkymist-ng
+  https://github.com/milkymist/misoc
 
 Send questions, comments and patches to devel [AT] lists.milkymist.org
 We are also on IRC: #milkymist on the Freenode network.
 
-Milkymist-ng is released under the very permissive two-clause BSD license. Under
-the terms of this license, you are authorized to use milkymist-ng for
+MiSoC is released under the very permissive two-clause BSD license. Under
+the terms of this license, you are authorized to use MiSoC for
 closed-source proprietary designs.
 Even though we do not require you to do so, those things are awesome, so please
 do them if possible:
- * tell us that you are using milkymist-ng
- * cite milkymist-ng in publications related to research it has helped
+ * tell us that you are using MiSoC
+ * cite MiSoC in publications related to research it has helped
  * send us feedback and suggestions for improvements
  * send us bug reports when something goes wrong
- * send us the modifications and improvements you have done to milkymist-ng.
+ * send us the modifications and improvements you have done to MiSoC.
    The use of "git format-patch" is recommended. If your submission is large and
    complex and/or you are not sure how to proceed, feel free to discuss it on
    the mailing list or IRC (#milkymist on Freenode) beforehand.
diff --git a/make.py b/make.py
index f70b6d6cef8d2839987d8f0136c4127229b04ae0..fc8548ff4dbb568656c939ec5d6c7b94e6bbf18e 100755 (executable)
--- a/make.py
+++ b/make.py
@@ -4,8 +4,8 @@ import argparse, os, importlib, subprocess
 
 from mibuild.tools import write_to_file
 
-from milkymist import cpuif
-from milkymist.s6ddrphy import initsequence
+from misoclib import cpuif
+from misoclib.s6ddrphy import initsequence
 import top, jtag
 
 def build(platform_name, build_bitstream, build_header, csr_csv_filename, *soc_args, **soc_kwargs):
@@ -57,7 +57,7 @@ TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG;
                write_to_file(csr_csv_filename, csr_csv)
 
 def main():
-       parser = argparse.ArgumentParser(description="milkymist-ng - a high performance SoC built on Migen technology.")
+       parser = argparse.ArgumentParser(description="MiSoC - a high performance SoC based on Migen.")
        parser.add_argument("-p", "--platform", default="mixxeo", help="platform to build for")
        parser.add_argument("-B", "--no-bitstream", default=False, action="store_true", help="do not build bitstream file")
        parser.add_argument("-H", "--no-header", default=False, action="store_true", help="do not build C header files with CSR/IRQ/SDRAM_PHY defs")
diff --git a/milkymist/__init__.py b/milkymist/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/milkymist/counteradc/__init__.py b/milkymist/counteradc/__init__.py
deleted file mode 100644 (file)
index 9df83c3..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-import collections
-
-from migen.fhdl.std import *
-from migen.bank.description import *
-from migen.genlib.misc import optree
-from migen.genlib.cdc import MultiReg
-
-class CounterADC(Module, AutoCSR):
-       def __init__(self, charge, sense, width=24):
-               if not isinstance(sense, collections.Iterable):
-                       sense = [sense]
-
-               channels = len(sense)
-
-               self._start_busy = CSR()
-               self._overflow = CSRStatus(channels)
-               self._polarity = CSRStorage()
-
-               count = Signal(width)
-               busy = Signal(channels)
-
-               res = []
-               for i in range(channels):
-                       res.append(CSRStatus(width, name="res"+str(i)))
-                       setattr(self, "_res"+str(i), res[-1])
-
-               any_busy = Signal()
-               self.comb += [
-                       any_busy.eq(optree("|",
-                           [busy[i] for i in range(channels)])),
-                       self._start_busy.w.eq(any_busy)
-               ]
-
-               carry = Signal()
-
-               self.sync += [
-                       If(self._start_busy.re,
-                               count.eq(0),
-                               busy.eq((1 << channels)-1),
-                               self._overflow.status.eq(0),
-                               charge.eq(~self._polarity.storage)
-                       ).Elif(any_busy,
-                               Cat(count, carry).eq(count + 1),
-                               If(carry,
-                                       self._overflow.status.eq(busy),
-                                       busy.eq(0)
-                               )
-                       ).Else(
-                               charge.eq(self._polarity.storage)
-                       )
-               ]
-
-               for i in range(channels):
-                       sense_synced = Signal()
-                       self.specials += MultiReg(sense[i], sense_synced)
-                       self.sync += If(busy[i],
-                               If(sense_synced != self._polarity.storage,
-                                       res[i].status.eq(count),
-                                       busy[i].eq(0)
-                               )
-                       )
diff --git a/milkymist/cpuif.py b/milkymist/cpuif.py
deleted file mode 100644 (file)
index b246774..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-from migen.bank.description import CSRStatus
-
-def _get_rw_functions(reg_name, reg_base, size, read_only):
-       r = ""
-       if size > 8:
-               raise NotImplementedError("Register too large")
-       elif size > 4:
-               ctype = "unsigned long long int"
-       elif size > 2:
-               ctype = "unsigned int"
-       elif size > 1:
-               ctype = "unsigned short int"
-       else:
-               ctype = "unsigned char"
-
-       r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
-       if size > 1:
-               r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
-               for byte in range(1, size):
-                       r += "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
-               r += "\treturn r;\n}\n"
-       else:
-               r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
-
-       if not read_only:
-               r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
-               for byte in range(size):
-                       shift = (size-byte-1)*8
-                       if shift:
-                               value_shifted = "value >> "+str(shift)
-                       else:
-                               value_shifted = "value"
-                       r += "\tMMPTR("+hex(reg_base+4*byte)+") = "+value_shifted+";\n"
-               r += "}\n"
-       return r
-
-def get_csr_header(csr_base, bank_array, interrupt_map):
-       r = "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
-       for name, csrs, mapaddr, rmap in bank_array.banks:
-               r += "\n/* "+name+" */\n"
-               reg_base = csr_base + 0x800*mapaddr
-               r += "#define "+name.upper()+"_BASE "+hex(reg_base)+"\n"
-               for csr in csrs:
-                       nr = (csr.size + 7)//8
-                       r += _get_rw_functions(name + "_" + csr.name, reg_base, nr, isinstance(csr, CSRStatus))
-                       reg_base += 4*nr
-               try:
-                       interrupt_nr = interrupt_map[name]
-               except KeyError:
-                       pass
-               else:
-                       r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n"
-       r += "\n#endif\n"
-       return r
-
-def get_csr_csv(csr_base, bank_array):
-       r = ""
-       for name, csrs, mapaddr, rmap in bank_array.banks:
-               reg_base = csr_base + 0x800*mapaddr
-               for csr in csrs:
-                       nr = (csr.size + 7)//8
-                       r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, reg_base, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
-                       reg_base += 4*nr
-       return r
diff --git a/milkymist/dfii/__init__.py b/milkymist/dfii/__init__.py
deleted file mode 100644 (file)
index 22a5bcd..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus import dfi
-from migen.bank.description import *
-
-class PhaseInjector(Module, AutoCSR):
-       def __init__(self, phase):
-               self._command = CSRStorage(6) # cs, we, cas, ras, wren, rden
-               self._command_issue = CSR()
-               self._address = CSRStorage(flen(phase.address))
-               self._baddress = CSRStorage(flen(phase.bank))
-               self._wrdata = CSRStorage(flen(phase.wrdata))
-               self._rddata = CSRStatus(flen(phase.rddata))
-       
-               ###
-
-               self.comb += [
-                       If(self._command_issue.re,
-                               phase.cs_n.eq(~self._command.storage[0]),
-                               phase.we_n.eq(~self._command.storage[1]),
-                               phase.cas_n.eq(~self._command.storage[2]),
-                               phase.ras_n.eq(~self._command.storage[3])
-                       ).Else(
-                               phase.cs_n.eq(1),
-                               phase.we_n.eq(1),
-                               phase.cas_n.eq(1),
-                               phase.ras_n.eq(1)
-                       ),
-                       phase.address.eq(self._address.storage),
-                       phase.bank.eq(self._baddress.storage),
-                       phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]),
-                       phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]),
-                       phase.wrdata.eq(self._wrdata.storage),
-                       phase.wrdata_mask.eq(0)
-               ]
-               self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
-
-class DFIInjector(Module, AutoCSR):
-       def __init__(self, a, ba, d, nphases=1):
-               inti = dfi.Interface(a, ba, d, nphases)
-               self.slave = dfi.Interface(a, ba, d, nphases)
-               self.master = dfi.Interface(a, ba, d, nphases)
-               
-               self._control = CSRStorage(2) # sel, cke
-               
-               for n, phase in enumerate(inti.phases):
-                       setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
-       
-               ###
-       
-               self.comb += If(self._control.storage[0],
-                               self.slave.connect(self.master)
-                       ).Else(
-                               inti.connect(self.master)
-                       )
-               self.comb += [phase.cke.eq(self._control.storage[1]) for phase in inti.phases]
diff --git a/milkymist/dvisampler/__init__.py b/milkymist/dvisampler/__init__.py
deleted file mode 100644 (file)
index c0227c1..0000000
+++ /dev/null
@@ -1,79 +0,0 @@
-from migen.fhdl.std import *
-from migen.bank.description import AutoCSR
-
-from milkymist.dvisampler.edid import EDID
-from milkymist.dvisampler.clocking import Clocking
-from milkymist.dvisampler.datacapture import DataCapture
-from milkymist.dvisampler.charsync import CharSync
-from milkymist.dvisampler.wer import WER
-from milkymist.dvisampler.decoding import Decoding
-from milkymist.dvisampler.chansync import ChanSync
-from milkymist.dvisampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
-from milkymist.dvisampler.dma import DMA
-
-class DVISampler(Module, AutoCSR):
-       def __init__(self, pads, asmiport, n_dma_slots=2):
-               self.submodules.edid = EDID(pads)
-               self.submodules.clocking = Clocking(pads)
-
-               for datan in range(3):
-                       name = "data" + str(datan)
-                       
-                       cap = DataCapture(getattr(pads, name + "_p"), getattr(pads, name + "_n"), 8)
-                       setattr(self.submodules, name + "_cap", cap)
-                       self.comb += cap.serdesstrobe.eq(self.clocking.serdesstrobe)
-
-                       charsync = CharSync()
-                       setattr(self.submodules, name + "_charsync", charsync)
-                       self.comb += charsync.raw_data.eq(cap.d)
-
-                       wer = WER()
-                       setattr(self.submodules, name + "_wer", wer)
-                       self.comb += wer.data.eq(charsync.data)
-
-                       decoding = Decoding()
-                       setattr(self.submodules, name + "_decod", decoding)
-                       self.comb += [
-                               decoding.valid_i.eq(charsync.synced),
-                               decoding.input.eq(charsync.data)
-                       ]
-
-               self.submodules.chansync = ChanSync()
-               self.comb += [
-                       self.chansync.valid_i.eq(self.data0_decod.valid_o & \
-                         self.data1_decod.valid_o & self.data2_decod.valid_o),
-                       self.chansync.data_in0.eq(self.data0_decod.output),
-                       self.chansync.data_in1.eq(self.data1_decod.output),
-                       self.chansync.data_in2.eq(self.data2_decod.output),
-               ]
-
-               self.submodules.syncpol = SyncPolarity()
-               self.comb += [
-                       self.syncpol.valid_i.eq(self.chansync.chan_synced),
-                       self.syncpol.data_in0.eq(self.chansync.data_out0),
-                       self.syncpol.data_in1.eq(self.chansync.data_out1),
-                       self.syncpol.data_in2.eq(self.chansync.data_out2)
-               ]
-
-               self.submodules.resdetection = ResolutionDetection()
-               self.comb += [
-                       self.resdetection.valid_i.eq(self.syncpol.valid_o),
-                       self.resdetection.de.eq(self.syncpol.de),
-                       self.resdetection.vsync.eq(self.syncpol.vsync)
-               ]
-
-               self.submodules.frame = FrameExtraction()
-               self.comb += [
-                       self.frame.valid_i.eq(self.syncpol.valid_o),
-                       self.frame.de.eq(self.syncpol.de),
-                       self.frame.vsync.eq(self.syncpol.vsync),
-                       self.frame.r.eq(self.syncpol.r),
-                       self.frame.g.eq(self.syncpol.g),
-                       self.frame.b.eq(self.syncpol.b)
-               ]
-
-               self.submodules.dma = DMA(asmiport, n_dma_slots)
-               self.comb += self.frame.frame.connect(self.dma.frame)
-               self.ev = self.dma.ev
-
-       autocsr_exclude = {"ev"}
diff --git a/milkymist/dvisampler/analysis.py b/milkymist/dvisampler/analysis.py
deleted file mode 100644 (file)
index c7d2478..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg, PulseSynchronizer
-from migen.genlib.fifo import AsyncFIFO
-from migen.genlib.record import Record
-from migen.bank.description import *
-from migen.flow.actor import *
-
-from milkymist.dvisampler.common import channel_layout, frame_layout
-
-class SyncPolarity(Module):
-       def __init__(self):
-               self.valid_i = Signal()
-               self.data_in0 = Record(channel_layout)
-               self.data_in1 = Record(channel_layout)
-               self.data_in2 = Record(channel_layout)
-
-               self.valid_o = Signal()
-               self.de = Signal()
-               self.hsync = Signal()
-               self.vsync = Signal()
-               self.r = Signal(8)
-               self.g = Signal(8)
-               self.b = Signal(8)
-
-               ###
-
-               de = self.data_in0.de
-               de_r = Signal()
-               c = self.data_in0.c
-               c_polarity = Signal(2)
-               c_out = Signal(2)
-
-               self.comb += [
-                       self.de.eq(de_r),
-                       self.hsync.eq(c_out[0]),
-                       self.vsync.eq(c_out[1])
-               ]
-
-               self.sync.pix += [
-                       self.valid_o.eq(self.valid_i),
-                       self.r.eq(self.data_in2.d),
-                       self.g.eq(self.data_in1.d),
-                       self.b.eq(self.data_in0.d),
-
-                       de_r.eq(de),
-                       If(de_r & ~de,
-                               c_polarity.eq(c),
-                               c_out.eq(0)
-                       ).Else(
-                               c_out.eq(c ^ c_polarity)
-                       )
-               ]
-
-class ResolutionDetection(Module, AutoCSR):
-       def __init__(self, nbits=11):
-               self.valid_i = Signal()
-               self.vsync = Signal()
-               self.de = Signal()
-
-               self._hres = CSRStatus(nbits)
-               self._vres = CSRStatus(nbits)
-
-               ###
-
-               # Detect DE transitions
-               de_r = Signal()
-               pn_de = Signal()
-               self.sync.pix += de_r.eq(self.de)
-               self.comb += pn_de.eq(~self.de & de_r)
-
-               # HRES
-               hcounter = Signal(nbits)
-               self.sync.pix += If(self.valid_i & self.de,
-                               hcounter.eq(hcounter + 1)
-                       ).Else(
-                               hcounter.eq(0)
-                       )
-
-               hcounter_st = Signal(nbits)
-               self.sync.pix += If(self.valid_i,
-                               If(pn_de, hcounter_st.eq(hcounter))
-                       ).Else(
-                               hcounter_st.eq(0)
-                       )
-               self.specials += MultiReg(hcounter_st, self._hres.status)
-
-               # VRES
-               vsync_r = Signal()
-               p_vsync = Signal()
-               self.sync.pix += vsync_r.eq(self.vsync),
-               self.comb += p_vsync.eq(self.vsync & ~vsync_r)
-
-               vcounter = Signal(nbits)
-               self.sync.pix += If(self.valid_i & p_vsync,
-                               vcounter.eq(0)
-                       ).Elif(pn_de,
-                               vcounter.eq(vcounter + 1)
-                       )
-
-               vcounter_st = Signal(nbits)
-               self.sync.pix += If(self.valid_i,
-                               If(p_vsync, vcounter_st.eq(vcounter))
-                       ).Else(
-                               vcounter_st.eq(0)
-                       )
-               self.specials += MultiReg(vcounter_st, self._vres.status)
-
-class FrameExtraction(Module, AutoCSR):
-       def __init__(self):
-               # in pix clock domain
-               self.valid_i = Signal()
-               self.vsync = Signal()
-               self.de = Signal()
-               self.r = Signal(8)
-               self.g = Signal(8)
-               self.b = Signal(8)
-
-               # in sys clock domain
-               self.frame = Source(frame_layout)
-               self.busy = Signal()
-
-               self._r_overflow = CSR()
-
-               ###
-
-               fifo_stb = Signal()
-               fifo_in = Record(frame_layout)
-               self.comb += [
-                       fifo_stb.eq(self.valid_i & self.de),
-                       fifo_in.r.eq(self.r),
-                       fifo_in.g.eq(self.g),
-                       fifo_in.b.eq(self.b),
-               ]
-               vsync_r = Signal()
-               self.sync.pix += [
-                       If(self.vsync & ~vsync_r, fifo_in.parity.eq(~fifo_in.parity)),
-                       vsync_r.eq(self.vsync)
-               ]
-
-               fifo = RenameClockDomains(AsyncFIFO(layout_len(frame_layout), 512),
-                       {"write": "pix", "read": "sys"})
-               self.submodules += fifo
-               self.comb += [
-                       fifo.we.eq(fifo_stb),
-                       fifo.din.eq(fifo_in.raw_bits()),
-                       self.frame.stb.eq(fifo.readable),
-                       self.frame.payload.raw_bits().eq(fifo.dout),
-                       fifo.re.eq(self.frame.ack),
-                       self.busy.eq(0)
-               ]
-
-               # overflow detection
-               pix_overflow = Signal()
-               pix_overflow_reset = Signal()
-               self.sync.pix += [
-                       If(fifo.we & ~fifo.writable,
-                               pix_overflow.eq(1)
-                       ).Elif(pix_overflow_reset,
-                               pix_overflow.eq(0)
-                       )
-               ]
-
-               sys_overflow = Signal()
-               self.specials += MultiReg(pix_overflow, sys_overflow)
-               self.submodules.overflow_reset = PulseSynchronizer("sys", "pix")
-               self.submodules.overflow_reset_ack = PulseSynchronizer("pix", "sys")
-               self.comb += [
-                       pix_overflow_reset.eq(self.overflow_reset.o),
-                       self.overflow_reset_ack.i.eq(pix_overflow_reset)
-               ]
-
-               overflow_mask = Signal()
-               self.comb += [
-                       self._r_overflow.w.eq(sys_overflow & ~overflow_mask),
-                       self.overflow_reset.i.eq(self._r_overflow.re)
-               ]
-               self.sync += [
-                       If(self._r_overflow.re,
-                               overflow_mask.eq(1)
-                       ).Elif(self.overflow_reset_ack.o,
-                               overflow_mask.eq(0)
-                       )
-               ]
diff --git a/milkymist/dvisampler/chansync.py b/milkymist/dvisampler/chansync.py
deleted file mode 100644 (file)
index 272408e..0000000
+++ /dev/null
@@ -1,88 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
-from migen.genlib.fifo import _inc
-from migen.genlib.record import Record, layout_len
-from migen.genlib.misc import optree
-from migen.bank.description import *
-
-from milkymist.dvisampler.common import channel_layout
-
-class _SyncBuffer(Module):
-       def __init__(self, width, depth):
-               self.din = Signal(width)
-               self.dout = Signal(width)
-               self.re = Signal()
-
-               ###
-
-               produce = Signal(max=depth)
-               consume = Signal(max=depth)
-               storage = Memory(width, depth)
-               self.specials += storage
-
-               wrport = storage.get_port(write_capable=True)
-               self.specials += wrport
-               self.comb += [
-                       wrport.adr.eq(produce),
-                       wrport.dat_w.eq(self.din),
-                       wrport.we.eq(1)
-               ]
-               self.sync += _inc(produce, depth)
-
-               rdport = storage.get_port(async_read=True)
-               self.specials += rdport
-               self.comb += [
-                       rdport.adr.eq(consume),
-                       self.dout.eq(rdport.dat_r)
-               ]
-               self.sync += If(self.re, _inc(consume, depth))
-
-class ChanSync(Module, AutoCSR):
-       def __init__(self, nchan=3, depth=8):
-               self.valid_i = Signal()
-               self.chan_synced = Signal()
-
-               self._r_channels_synced = CSRStatus()
-
-               lst_control = []
-               all_control = Signal()
-               for i in range(nchan):
-                       name = "data_in" + str(i)
-                       data_in = Record(channel_layout, name=name)
-                       setattr(self, name, data_in)
-                       name = "data_out" + str(i)
-                       data_out = Record(channel_layout, name=name)
-                       setattr(self, name, data_out)
-
-                       ###
-               
-                       syncbuffer = RenameClockDomains(_SyncBuffer(layout_len(channel_layout), depth), "pix")
-                       self.submodules += syncbuffer
-                       self.comb += [
-                               syncbuffer.din.eq(data_in.raw_bits()),
-                               data_out.raw_bits().eq(syncbuffer.dout)
-                       ]
-                       is_control = Signal()
-                       self.comb += [
-                               is_control.eq(~data_out.de),
-                               syncbuffer.re.eq(~is_control | all_control)
-                       ]
-                       lst_control.append(is_control)
-
-               some_control = Signal()
-               self.comb += [
-                       all_control.eq(optree("&", lst_control)),
-                       some_control.eq(optree("|", lst_control))
-               ]
-               self.sync.pix += If(~self.valid_i,
-                               self.chan_synced.eq(0)
-                       ).Else(
-                               If(some_control,
-                                       If(all_control,
-                                               self.chan_synced.eq(1)
-                                       ).Else(
-                                               self.chan_synced.eq(0)
-                                       )
-                               )
-                       )
-               self.specials += MultiReg(self.chan_synced, self._r_channels_synced.status)
diff --git a/milkymist/dvisampler/charsync.py b/milkymist/dvisampler/charsync.py
deleted file mode 100644 (file)
index 92e38e9..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
-from migen.genlib.misc import optree
-from migen.bank.description import *
-
-from milkymist.dvisampler.common import control_tokens
-
-class CharSync(Module, AutoCSR):
-       def __init__(self, required_controls=8):
-               self.raw_data = Signal(10)
-               self.synced = Signal()
-               self.data = Signal(10)
-
-               self._r_char_synced = CSRStatus()
-               self._r_ctl_pos = CSRStatus(bits_for(9))
-
-               ###
-
-               raw_data1 = Signal(10)
-               self.sync.pix += raw_data1.eq(self.raw_data)
-               raw = Signal(20)
-               self.comb += raw.eq(Cat(raw_data1, self.raw_data))
-
-               found_control = Signal()
-               control_position = Signal(max=10)
-               self.sync.pix += found_control.eq(0)
-               for i in range(10):
-                       self.sync.pix += If(optree("|", [raw[i:i+10] == t for t in control_tokens]),
-                               found_control.eq(1),
-                               control_position.eq(i)
-                       )
-
-               control_counter = Signal(max=required_controls)
-               previous_control_position = Signal(max=10)
-               word_sel = Signal(max=10)
-               self.sync.pix += [
-                       If(found_control & (control_position == previous_control_position),
-                               If(control_counter == (required_controls - 1),
-                                       control_counter.eq(0),
-                                       self.synced.eq(1),
-                                       word_sel.eq(control_position)
-                               ).Else(
-                                       control_counter.eq(control_counter + 1)
-                               )
-                       ).Else(
-                               control_counter.eq(0)
-                       ),
-                       previous_control_position.eq(control_position)
-               ]
-               self.specials += MultiReg(self.synced, self._r_char_synced.status)
-               self.specials += MultiReg(word_sel, self._r_ctl_pos.status)
-
-               self.sync.pix += self.data.eq(raw >> word_sel)
diff --git a/milkymist/dvisampler/clocking.py b/milkymist/dvisampler/clocking.py
deleted file mode 100644 (file)
index bcfca52..0000000
+++ /dev/null
@@ -1,57 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-
-class Clocking(Module, AutoCSR):
-       def __init__(self, pads):
-               self._r_pll_reset = CSRStorage(reset=1)
-               self._r_locked = CSRStatus()
-
-               self.locked = Signal()
-               self.serdesstrobe = Signal()
-               self.clock_domains._cd_pix = ClockDomain()
-               self.clock_domains._cd_pix2x = ClockDomain()
-               self.clock_domains._cd_pix10x = ClockDomain(reset_less=True)
-
-               ###
-
-               clk_se = Signal()
-               self.specials += Instance("IBUFDS", i_I=pads.clk_p, i_IB=pads.clk_n, o_O=clk_se)
-
-               clkfbout = Signal()
-               pll_locked = Signal()
-               pll_clk0 = Signal()
-               pll_clk1 = Signal()
-               pll_clk2 = Signal()
-               self.specials += Instance("PLL_BASE",
-                       p_CLKIN_PERIOD=26.7,
-                       p_CLKFBOUT_MULT=20,
-                       p_CLKOUT0_DIVIDE=2,  # pix10x
-                       p_CLKOUT1_DIVIDE=10, # pix2x
-                       p_CLKOUT2_DIVIDE=20, # pix
-                       p_COMPENSATION="INTERNAL",
-                       
-                       i_CLKIN=clk_se,
-                       o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
-                       o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
-                       o_LOCKED=pll_locked, i_RST=self._r_pll_reset.storage)
-
-               locked_async = Signal()
-               self.specials += [
-                       Instance("BUFPLL", p_DIVIDE=5,
-                               i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
-                               o_IOCLK=self._cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
-                       Instance("BUFG", i_I=pll_clk1, o_O=self._cd_pix2x.clk),
-                       Instance("BUFG", i_I=pll_clk2, o_O=self._cd_pix.clk),
-                       MultiReg(locked_async, self.locked, "sys")
-               ]
-               self.comb += self._r_locked.status.eq(self.locked)
-
-               # sychronize pix+pix2x reset
-               pix_rst_n = 1
-               for i in range(2):
-                       new_pix_rst_n = Signal()
-                       self.specials += Instance("FDCE", i_D=pix_rst_n, i_CE=1, i_C=ClockSignal("pix"),
-                               i_CLR=~locked_async, o_Q=new_pix_rst_n)
-                       pix_rst_n = new_pix_rst_n
-               self.comb += self._cd_pix.rst.eq(~pix_rst_n), self._cd_pix2x.rst.eq(~pix_rst_n)
diff --git a/milkymist/dvisampler/common.py b/milkymist/dvisampler/common.py
deleted file mode 100644 (file)
index f053237..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
-channel_layout = [("d", 8), ("c", 2), ("de", 1)]
-frame_layout = [("parity", 1), ("r", 8), ("g", 8), ("b", 8)]
diff --git a/milkymist/dvisampler/datacapture.py b/milkymist/dvisampler/datacapture.py
deleted file mode 100644 (file)
index d788843..0000000
+++ /dev/null
@@ -1,186 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg, PulseSynchronizer
-from migen.bank.description import *
-
-class DataCapture(Module, AutoCSR):
-       def __init__(self, pad_p, pad_n, ntbits):
-               self.serdesstrobe = Signal()
-               self.d = Signal(10)
-
-               self._r_dly_ctl = CSR(6)
-               self._r_dly_busy = CSRStatus(2)
-               self._r_phase = CSRStatus(2)
-               self._r_phase_reset = CSR()
-
-               ###
-
-               # IO
-               pad_se = Signal()
-               self.specials += Instance("IBUFDS", i_I=pad_p, i_IB=pad_n, o_O=pad_se)
-
-               pad_delayed_master = Signal()
-               pad_delayed_slave = Signal()
-               delay_inc = Signal()
-               delay_ce = Signal()
-               delay_master_cal = Signal()
-               delay_master_rst = Signal()
-               delay_master_busy = Signal()
-               delay_slave_cal = Signal()
-               delay_slave_rst = Signal()
-               delay_slave_busy = Signal()
-               self.specials += Instance("IODELAY2",
-                       p_SERDES_MODE="MASTER",
-                       p_DELAY_SRC="IDATAIN", p_IDELAY_TYPE="DIFF_PHASE_DETECTOR",
-                       p_COUNTER_WRAPAROUND="STAY_AT_LIMIT", p_DATA_RATE="SDR",
-
-                       i_IDATAIN=pad_se, o_DATAOUT=pad_delayed_master,
-                       i_CLK=ClockSignal("pix2x"), i_IOCLK0=ClockSignal("pix10x"),
-
-                       i_INC=delay_inc, i_CE=delay_ce,
-                       i_CAL=delay_master_cal, i_RST=delay_master_rst, o_BUSY=delay_master_busy,
-                       i_T=1)
-               self.specials += Instance("IODELAY2",
-                       p_SERDES_MODE="SLAVE",
-                       p_DELAY_SRC="IDATAIN", p_IDELAY_TYPE="DIFF_PHASE_DETECTOR",
-                       p_COUNTER_WRAPAROUND="WRAPAROUND", p_DATA_RATE="SDR",
-
-                       i_IDATAIN=pad_se, o_DATAOUT=pad_delayed_slave,
-                       i_CLK=ClockSignal("pix2x"), i_IOCLK0=ClockSignal("pix10x"),
-
-                       i_INC=delay_inc, i_CE=delay_ce,
-                       i_CAL=delay_slave_cal, i_RST=delay_slave_rst, o_BUSY=delay_slave_busy,
-                       i_T=1)
-
-               dsr2 = Signal(5)
-               pd_valid = Signal()
-               pd_incdec = Signal()
-               pd_edge = Signal()
-               pd_cascade = Signal()
-               self.specials += Instance("ISERDES2",
-                       p_SERDES_MODE="MASTER",
-                       p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=5,
-                       p_INTERFACE_TYPE="RETIMED",
-
-                       i_D=pad_delayed_master,
-                       o_Q4=dsr2[4], o_Q3=dsr2[3], o_Q2=dsr2[2], o_Q1=dsr2[1],
-
-                       i_BITSLIP=0, i_CE0=1, i_RST=0,
-                       i_CLK0=ClockSignal("pix10x"), i_CLKDIV=ClockSignal("pix2x"),
-                       i_IOCE=self.serdesstrobe,
-
-                       o_VALID=pd_valid, o_INCDEC=pd_incdec,
-                       i_SHIFTIN=pd_edge, o_SHIFTOUT=pd_cascade)
-               self.specials += Instance("ISERDES2",
-                       p_SERDES_MODE="SLAVE",
-                       p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=5,
-                       p_INTERFACE_TYPE="RETIMED",
-
-                       i_D=pad_delayed_slave,
-                       o_Q4=dsr2[0],
-
-                       i_BITSLIP=0, i_CE0=1, i_RST=0,
-                       i_CLK0=ClockSignal("pix10x"), i_CLKDIV=ClockSignal("pix2x"),
-                       i_IOCE=self.serdesstrobe,
-
-                       i_SHIFTIN=pd_cascade, o_SHIFTOUT=pd_edge)
-
-               # Phase error accumulator
-               lateness = Signal(ntbits, reset=2**(ntbits - 1))
-               too_late = Signal()
-               too_early = Signal()
-               reset_lateness = Signal()
-               self.comb += [
-                       too_late.eq(lateness == (2**ntbits - 1)),
-                       too_early.eq(lateness == 0)
-               ]
-               self.sync.pix2x += [
-                       If(reset_lateness,
-                               lateness.eq(2**(ntbits - 1))
-                       ).Elif(~delay_master_busy & ~delay_slave_busy & ~too_late & ~too_early,
-                               If(pd_valid &  pd_incdec, lateness.eq(lateness - 1)),
-                               If(pd_valid & ~pd_incdec, lateness.eq(lateness + 1))
-                       )
-               ]
-
-               # Delay control
-               self.submodules.delay_master_done = PulseSynchronizer("pix2x", "sys")
-               delay_master_pending = Signal()
-               self.sync.pix2x += [
-                       self.delay_master_done.i.eq(0),
-                       If(~delay_master_pending,
-                               If(delay_master_cal | delay_ce, delay_master_pending.eq(1))
-                       ).Else(
-                               If(~delay_master_busy,
-                                       self.delay_master_done.i.eq(1),
-                                       delay_master_pending.eq(0)
-                               )
-                       )
-               ]
-               self.submodules.delay_slave_done = PulseSynchronizer("pix2x", "sys")
-               delay_slave_pending = Signal()
-               self.sync.pix2x += [
-                       self.delay_slave_done.i.eq(0),
-                       If(~delay_slave_pending,
-                               If(delay_slave_cal | delay_ce, delay_slave_pending.eq(1))
-                       ).Else(
-                               If(~delay_slave_busy,
-                                       self.delay_slave_done.i.eq(1),
-                                       delay_slave_pending.eq(0)
-                               )
-                       )
-               ]
-
-               self.submodules.do_delay_master_cal = PulseSynchronizer("sys", "pix2x")
-               self.submodules.do_delay_master_rst = PulseSynchronizer("sys", "pix2x")
-               self.submodules.do_delay_slave_cal = PulseSynchronizer("sys", "pix2x")
-               self.submodules.do_delay_slave_rst = PulseSynchronizer("sys", "pix2x")
-               self.submodules.do_delay_inc = PulseSynchronizer("sys", "pix2x")
-               self.submodules.do_delay_dec = PulseSynchronizer("sys", "pix2x")
-               self.comb += [
-                       delay_master_cal.eq(self.do_delay_master_cal.o),
-                       delay_master_rst.eq(self.do_delay_master_rst.o),
-                       delay_slave_cal.eq(self.do_delay_slave_cal.o),
-                       delay_slave_rst.eq(self.do_delay_slave_rst.o),
-                       delay_inc.eq(self.do_delay_inc.o),
-                       delay_ce.eq(self.do_delay_inc.o | self.do_delay_dec.o),
-               ]
-
-               sys_delay_master_pending = Signal()
-               self.sync += [
-                       If(self.do_delay_master_cal.i | self.do_delay_inc.i | self.do_delay_dec.i,
-                               sys_delay_master_pending.eq(1)
-                       ).Elif(self.delay_master_done.o,
-                               sys_delay_master_pending.eq(0)
-                       )
-               ]
-               sys_delay_slave_pending = Signal()
-               self.sync += [
-                       If(self.do_delay_slave_cal.i | self.do_delay_inc.i | self.do_delay_dec.i,
-                               sys_delay_slave_pending.eq(1)
-                       ).Elif(self.delay_slave_done.o,
-                               sys_delay_slave_pending.eq(0)
-                       )
-               ]
-
-               self.comb += [
-                       self.do_delay_master_cal.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[0]),
-                       self.do_delay_master_rst.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[1]),
-                       self.do_delay_slave_cal.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[2]),
-                       self.do_delay_slave_rst.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[3]),
-                       self.do_delay_inc.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[4]),
-                       self.do_delay_dec.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[5]),
-                       self._r_dly_busy.status.eq(Cat(sys_delay_master_pending, sys_delay_slave_pending))
-               ]
-
-               # Phase detector control
-               self.specials += MultiReg(Cat(too_late, too_early), self._r_phase.status)
-               self.submodules.do_reset_lateness = PulseSynchronizer("sys", "pix2x")
-               self.comb += [
-                       reset_lateness.eq(self.do_reset_lateness.o),
-                       self.do_reset_lateness.i.eq(self._r_phase_reset.re)
-               ]
-
-               # 5:10 deserialization
-               dsr = Signal(10)
-               self.sync.pix2x += dsr.eq(Cat(dsr[5:], dsr2))
-               self.sync.pix += self.d.eq(dsr)
diff --git a/milkymist/dvisampler/debug.py b/milkymist/dvisampler/debug.py
deleted file mode 100644 (file)
index 3932664..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.fifo import AsyncFIFO
-from migen.genlib.record import layout_len
-from migen.bank.description import AutoCSR
-from migen.actorlib import structuring, dma_lasmi, spi
-
-from milkymist.dvisampler.edid import EDID
-from milkymist.dvisampler.clocking import Clocking
-from milkymist.dvisampler.datacapture import DataCapture
-
-class RawDVISampler(Module, AutoCSR):
-       def __init__(self, pads, asmiport):
-               self.submodules.edid = EDID(pads)
-               self.submodules.clocking = Clocking(pads)
-
-               invert = False
-               try:
-                       s = getattr(pads, "data0")
-               except AttributeError:
-                       s = getattr(pads, "data0_n")
-                       invert = True
-               self.submodules.data0_cap = DataCapture(8, invert)
-               self.comb += [
-                       self.data0_cap.pad.eq(s),
-                       self.data0_cap.serdesstrobe.eq(self.clocking.serdesstrobe)
-               ]
-
-               fifo = RenameClockDomains(AsyncFIFO(10, 256),
-                       {"write": "pix", "read": "sys"})
-               self.submodules += fifo
-               self.comb += [
-                       fifo.din.eq(self.data0_cap.d),
-                       fifo.we.eq(1)
-               ]
-
-               pack_factor = asmiport.hub.dw//16
-               self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor)
-               self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw)
-               self.submodules.dma = spi.DMAWriteController(dma_lasmi.Writer(lasmim), spi.MODE_SINGLE_SHOT)
-               self.comb += [
-                       self.packer.sink.stb.eq(fifo.readable),
-                       fifo.re.eq(self.packer.sink.ack),
-                       self.packer.sink.payload.word.eq(fifo.dout),
-                       self.packer.source.connect_flat(self.cast.sink),
-                       self.cast.source.connect_flat(self.dma.data)
-               ]
diff --git a/milkymist/dvisampler/decoding.py b/milkymist/dvisampler/decoding.py
deleted file mode 100644 (file)
index 034f454..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.record import Record
-
-from milkymist.dvisampler.common import control_tokens, channel_layout
-
-class Decoding(Module):
-       def __init__(self):
-               self.valid_i = Signal()
-               self.input = Signal(10)
-               self.valid_o = Signal()
-               self.output = Record(channel_layout)
-
-               ###
-
-               self.sync.pix += self.output.de.eq(1)
-               for i, t in enumerate(control_tokens):
-                       self.sync.pix += If(self.input == t,
-                               self.output.de.eq(0),
-                               self.output.c.eq(i)
-                       )
-               self.sync.pix += self.output.d[0].eq(self.input[0] ^ self.input[9])
-               for i in range(1, 8):
-                       self.sync.pix += self.output.d[i].eq(self.input[i] ^ self.input[i-1] ^ ~self.input[8])
-               self.sync.pix += self.valid_o.eq(self.valid_i)
diff --git a/milkymist/dvisampler/dma.py b/milkymist/dvisampler/dma.py
deleted file mode 100644 (file)
index d1cfce5..0000000
+++ /dev/null
@@ -1,156 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.fsm import FSM, NextState
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-from migen.flow.actor import *
-from migen.actorlib import dma_lasmi
-
-from milkymist.dvisampler.common import frame_layout
-
-# Slot status: EMPTY=0 LOADED=1 PENDING=2
-class _Slot(Module, AutoCSR):
-       def __init__(self, addr_bits, alignment_bits):
-               self.ev_source = EventSourceLevel()
-               self.address = Signal(addr_bits)
-               self.address_valid = Signal()
-               self.address_done = Signal()
-
-               self._r_status = CSRStorage(2, write_from_dev=True)
-               self._r_address = CSRStorage(addr_bits + alignment_bits, alignment_bits=alignment_bits)
-
-               ###
-
-               self.comb += [
-                       self.address.eq(self._r_address.storage),
-                       self.address_valid.eq(self._r_status.storage[0]),
-                       self._r_status.dat_w.eq(2),
-                       self._r_status.we.eq(self.address_done),
-                       self.ev_source.trigger.eq(self._r_status.storage[1])
-               ]
-
-class _SlotArray(Module, AutoCSR):
-       def __init__(self, nslots, addr_bits, alignment_bits):
-               self.submodules.ev = EventManager()
-               self.address = Signal(addr_bits)
-               self.address_valid = Signal()
-               self.address_done = Signal()
-
-               ###
-
-               slots = [_Slot(addr_bits, alignment_bits) for i in range(nslots)]
-               for n, slot in enumerate(slots):
-                       setattr(self.submodules, "slot"+str(n), slot)
-                       setattr(self.ev, "slot"+str(n), slot.ev_source)
-               self.ev.finalize()
-
-               change_slot = Signal()
-               current_slot = Signal(max=nslots)
-               self.sync += If(change_slot, [If(slot.address_valid, current_slot.eq(n)) for n, slot in reversed(list(enumerate(slots)))])
-               self.comb += change_slot.eq(~self.address_valid | self.address_done)
-
-               self.comb += [
-                       self.address.eq(Array(slot.address for slot in slots)[current_slot]),
-                       self.address_valid.eq(Array(slot.address_valid for slot in slots)[current_slot])
-               ]
-               self.comb += [slot.address_done.eq(self.address_done & (current_slot == n)) for n, slot in enumerate(slots)]
-
-class DMA(Module):
-       def __init__(self, lasmim, nslots):
-               bus_aw = lasmim.aw
-               bus_dw = lasmim.dw
-               alignment_bits = bits_for(bus_dw//8) - 1
-
-               self.frame = Sink(frame_layout)
-               self._r_frame_size = CSRStorage(bus_aw + alignment_bits, alignment_bits=alignment_bits)
-               self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits)
-               self.ev = self._slot_array.ev
-
-               ###
-
-               # start of frame detection
-               sof = Signal()
-               parity_r = Signal()
-               self.sync += If(self.frame.stb & self.frame.ack, parity_r.eq(self.frame.payload.parity))
-               self.comb += sof.eq(parity_r ^ self.frame.payload.parity)
-
-               # address generator + maximum memory word count to prevent DMA buffer overrun
-               reset_words = Signal()
-               count_word = Signal()
-               last_word = Signal()
-               current_address = Signal(bus_aw)
-               mwords_remaining = Signal(bus_aw)
-               self.comb += last_word.eq(mwords_remaining == 1)
-               self.sync += [
-                       If(reset_words,
-                               current_address.eq(self._slot_array.address),
-                               mwords_remaining.eq(self._r_frame_size.storage)
-                       ).Elif(count_word,
-                               current_address.eq(current_address + 1),
-                               mwords_remaining.eq(mwords_remaining - 1)
-                       )
-               ]
-
-               # pack pixels into memory words
-               write_pixel = Signal()
-               last_pixel = Signal()
-               cur_memory_word = Signal(bus_dw)
-               encoded_pixel = Signal(32)
-               self.comb += [
-                       encoded_pixel.eq(Cat(
-                               self.frame.payload.b[6:], self.frame.payload.b,
-                               self.frame.payload.g[6:], self.frame.payload.g,
-                               self.frame.payload.r[6:], self.frame.payload.r))
-               ]
-               pack_factor = bus_dw//32
-               assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2
-               pack_counter = Signal(max=pack_factor)
-               self.comb += last_pixel.eq(pack_counter == (pack_factor - 1))
-               self.sync += If(write_pixel,
-                               [If(pack_counter == (pack_factor-i-1),
-                                       cur_memory_word[32*i:32*(i+1)].eq(encoded_pixel)) for i in range(pack_factor)],
-                               pack_counter.eq(pack_counter + 1)
-                       )
-
-               # bus accessor
-               self.submodules._bus_accessor = dma_lasmi.Writer(lasmim)
-               self.comb += [
-                       self._bus_accessor.address_data.payload.a.eq(current_address),
-                       self._bus_accessor.address_data.payload.d.eq(cur_memory_word)
-               ]
-
-               # control FSM
-               fsm = FSM()
-               self.submodules += fsm
-
-               fsm.act("WAIT_SOF",
-                       reset_words.eq(1),
-                       self.frame.ack.eq(~self._slot_array.address_valid | ~sof),
-                       If(self._slot_array.address_valid & sof & self.frame.stb, NextState("TRANSFER_PIXEL"))
-               )
-               fsm.act("TRANSFER_PIXEL",
-                       self.frame.ack.eq(1),
-                       If(self.frame.stb,
-                               write_pixel.eq(1),
-                               If(last_pixel, NextState("TO_MEMORY"))
-                       )
-               )
-               fsm.act("TO_MEMORY",
-                       self._bus_accessor.address_data.stb.eq(1),
-                       If(self._bus_accessor.address_data.ack,
-                               count_word.eq(1),
-                               If(last_word,
-                                       NextState("EOF")
-                               ).Else(
-                                       NextState("TRANSFER_PIXEL")
-                               )
-                       )
-               )
-               fsm.act("EOF",
-                       If(~self._bus_accessor.busy,
-                               self._slot_array.address_done.eq(1),
-                               NextState("WAIT_SOF")
-                       )
-               )
-
-       def get_csrs(self):
-               return [self._r_frame_size] + self._slot_array.get_csrs()
diff --git a/milkymist/dvisampler/edid.py b/milkymist/dvisampler/edid.py
deleted file mode 100644 (file)
index b4afb4e..0000000
+++ /dev/null
@@ -1,189 +0,0 @@
-from migen.fhdl.std import *
-from migen.fhdl.specials import Tristate
-from migen.genlib.cdc import MultiReg
-from migen.genlib.fsm import FSM, NextState
-from migen.genlib.misc import chooser
-from migen.bank.description import CSRStorage, CSRStatus, AutoCSR
-
-_default_edid = [
-       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3D, 0x17, 0x32, 0x12, 0x2A, 0x6A, 0xBF, 0x00,
-       0x05, 0x17, 0x01, 0x03, 0x80, 0x28, 0x1E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xB2, 0x0C, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88,
-       0x36, 0x00, 0x28, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x4D, 0x31, 0x20,
-       0x44, 0x56, 0x49, 0x20, 0x6D, 0x69, 0x78, 0x65, 0x72, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
-       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
-]
-
-class EDID(Module, AutoCSR):
-       def __init__(self, pads, default=_default_edid):
-               self._r_hpd_notif = CSRStatus()
-               self._r_hpd_en = CSRStorage()
-               self.specials.mem = Memory(8, 128, init=default)
-
-               ###
-
-               # HPD
-               if hasattr(pads, "hpd_notif"):
-                       self.specials += MultiReg(pads.hpd_notif, self._r_hpd_notif.status)
-               else:
-                       self.comb += self._r_hpd_notif.status.eq(1)
-               if hasattr(pads, "hpd_en"):
-                       self.comb += pads.hpd_en.eq(self._r_hpd_en.storage)
-
-               # EDID
-               scl_raw = Signal()
-               sda_i = Signal()
-               sda_drv = Signal()
-               _sda_drv_reg = Signal()
-               _sda_i_async = Signal()
-               self.sync += _sda_drv_reg.eq(sda_drv)
-               self.specials += [
-                       MultiReg(pads.scl, scl_raw),
-                       Tristate(pads.sda, 0, _sda_drv_reg, _sda_i_async),
-                       MultiReg(_sda_i_async, sda_i)
-               ]
-
-               scl_i = Signal()
-               samp_count = Signal(6)
-               samp_carry = Signal()
-               self.sync += [
-                       Cat(samp_count, samp_carry).eq(samp_count + 1),
-                       If(samp_carry, scl_i.eq(scl_raw))
-               ]
-
-               scl_r = Signal()
-               sda_r = Signal()
-               scl_rising = Signal()
-               sda_rising = Signal()
-               sda_falling = Signal()
-               self.sync += [
-                       scl_r.eq(scl_i),
-                       sda_r.eq(sda_i)
-               ]
-               self.comb += [
-                       scl_rising.eq(scl_i & ~scl_r),
-                       sda_rising.eq(sda_i & ~sda_r),
-                       sda_falling.eq(~sda_i & sda_r)
-               ]
-
-               start = Signal()
-               self.comb += start.eq(scl_i & sda_falling)
-
-               din = Signal(8)
-               counter = Signal(max=9)
-               self.sync += [
-                       If(start, counter.eq(0)),
-                       If(scl_rising,
-                               If(counter == 8,
-                                       counter.eq(0)
-                               ).Else(
-                                       counter.eq(counter + 1),
-                                       din.eq(Cat(sda_i, din[:7]))
-                               )
-                       )
-               ]
-
-               is_read = Signal()
-               update_is_read = Signal()
-               self.sync += If(update_is_read, is_read.eq(din[0]))
-
-               offset_counter = Signal(max=128)
-               oc_load = Signal()
-               oc_inc = Signal()
-               self.sync += [
-                       If(oc_load,
-                               offset_counter.eq(din)
-                       ).Elif(oc_inc,
-                               offset_counter.eq(offset_counter + 1)
-                       )
-               ]
-               rdport = self.mem.get_port()
-               self.specials += rdport
-               self.comb += rdport.adr.eq(offset_counter)
-               data_bit = Signal()
-
-               zero_drv = Signal()
-               data_drv = Signal()
-               self.comb += If(zero_drv, sda_drv.eq(1)).Elif(data_drv, sda_drv.eq(~data_bit))
-
-               data_drv_en = Signal()
-               data_drv_stop = Signal()
-               self.sync += If(data_drv_en, data_drv.eq(1)).Elif(data_drv_stop, data_drv.eq(0))
-               self.sync += If(data_drv_en, chooser(rdport.dat_r, counter, data_bit, 8, reverse=True))
-
-               fsm = FSM()
-               self.submodules += fsm
-       
-               fsm.act("WAIT_START")
-               fsm.act("RCV_ADDRESS",
-                       If(counter == 8,
-                               If(din[1:] == 0x50,
-                                       update_is_read.eq(1),
-                                       NextState("ACK_ADDRESS0")
-                               ).Else(
-                                       NextState("WAIT_START")
-                               )
-                       )
-               )
-               fsm.act("ACK_ADDRESS0",
-                       If(~scl_i, NextState("ACK_ADDRESS1"))
-               )
-               fsm.act("ACK_ADDRESS1",
-                       zero_drv.eq(1),
-                       If(scl_i, NextState("ACK_ADDRESS2"))
-               )
-               fsm.act("ACK_ADDRESS2",
-                       zero_drv.eq(1),
-                       If(~scl_i,
-                               If(is_read,
-                                       NextState("READ")
-                               ).Else(
-                                       NextState("RCV_OFFSET")
-                               )
-                       )
-               )
-
-               fsm.act("RCV_OFFSET",
-                       If(counter == 8,
-                               oc_load.eq(1),
-                               NextState("ACK_OFFSET0")
-                       )
-               )
-               fsm.act("ACK_OFFSET0",
-                       If(~scl_i, NextState("ACK_OFFSET1"))
-               )
-               fsm.act("ACK_OFFSET1",
-                       zero_drv.eq(1),
-                       If(scl_i, NextState("ACK_OFFSET2"))
-               )
-               fsm.act("ACK_OFFSET2",
-                       zero_drv.eq(1),
-                       If(~scl_i, NextState("RCV_ADDRESS"))
-               )
-
-               fsm.act("READ",
-                       If(~scl_i,
-                               If(counter == 8,
-                                       data_drv_stop.eq(1),
-                                       NextState("ACK_READ")
-                               ).Else(
-                                       data_drv_en.eq(1)
-                               )
-                       )
-               )
-               fsm.act("ACK_READ",
-                       If(scl_rising,
-                               oc_inc.eq(1),
-                               If(sda_i,
-                                       NextState("WAIT_START")
-                               ).Else(
-                                       NextState("READ")
-                               )
-                       )
-               )
-
-               for state in fsm.actions.keys():
-                       fsm.act(state, If(start, NextState("RCV_ADDRESS")))
-                       fsm.act(state, If(~self._r_hpd_en.storage, NextState("WAIT_START")))
diff --git a/milkymist/dvisampler/wer.py b/milkymist/dvisampler/wer.py
deleted file mode 100644 (file)
index 89d89a0..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-from migen.fhdl.std import *
-from migen.bank.description import *
-from migen.genlib.misc import optree
-from migen.genlib.cdc import PulseSynchronizer
-
-from milkymist.dvisampler.common import control_tokens
-
-class WER(Module, AutoCSR):
-       def __init__(self, period_bits=24):
-               self.data = Signal(10)
-               self._r_update = CSR()
-               self._r_value = CSRStatus(period_bits)
-
-               ###
-
-               # pipeline stage 1
-               # we ignore the 10th (inversion) bit, as it is independent of the transition minimization
-               data_r = Signal(9)
-               self.sync.pix += data_r.eq(self.data[:9])
-
-               # pipeline stage 2
-               transitions = Signal(8)
-               self.comb += [transitions[i].eq(data_r[i] ^ data_r[i+1]) for i in range(8)]
-               transition_count = Signal(max=9)
-               self.sync.pix += transition_count.eq(optree("+", [transitions[i] for i in range(8)]))
-
-               is_control = Signal()
-               self.sync.pix += is_control.eq(optree("|", [data_r == ct for ct in control_tokens]))
-
-               # pipeline stage 3
-               is_error = Signal()
-               self.sync.pix += is_error.eq((transition_count > 4) & ~is_control)
-
-               # counter
-               period_counter = Signal(period_bits)
-               period_done = Signal()
-               self.sync.pix += Cat(period_counter, period_done).eq(period_counter + 1)
-
-               wer_counter = Signal(period_bits)
-               wer_counter_r = Signal(period_bits)
-               wer_counter_r_updated = Signal()
-               self.sync.pix += [
-                       wer_counter_r_updated.eq(period_done),
-                       If(period_done,
-                               wer_counter_r.eq(wer_counter),
-                               wer_counter.eq(0)
-                       ).Elif(is_error,
-                               wer_counter.eq(wer_counter + 1)
-                       )
-               ]
-
-               # sync to system clock domain
-               wer_counter_sys = Signal(period_bits)
-               self.submodules.ps_counter = PulseSynchronizer("pix", "sys")
-               self.comb += self.ps_counter.i.eq(wer_counter_r_updated)
-               self.sync += If(self.ps_counter.o, wer_counter_sys.eq(wer_counter_r))
-
-               # register interface
-               self.sync += If(self._r_update.re, self._r_value.status.eq(wer_counter_sys))
diff --git a/milkymist/framebuffer/__init__.py b/milkymist/framebuffer/__init__.py
deleted file mode 100644 (file)
index eb64208..0000000
+++ /dev/null
@@ -1,110 +0,0 @@
-from migen.fhdl.std import *
-from migen.flow.actor import *
-from migen.flow.network import *
-from migen.bank.description import CSRStorage, AutoCSR
-from migen.actorlib import dma_lasmi, structuring, sim, spi
-
-from milkymist.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG
-from milkymist.framebuffer.phy import Driver
-
-class Framebuffer(Module, AutoCSR):
-       def __init__(self, pads_vga, pads_dvi, lasmim, simulation=False):
-               pack_factor = lasmim.dw//(2*bpp)
-               packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
-               
-               self._enable = CSRStorage()
-               self.fi = FrameInitiator()
-               self.dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
-               self.driver = Driver(pads_vga, pads_dvi)
-
-               cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
-               unpack = structuring.Unpack(pack_factor, pixel_layout)
-               vtg = VTG()
-               
-               g = DataFlowGraph()
-               g.add_connection(self.fi, vtg, sink_ep="timing")
-               g.add_connection(self.dma, cast)
-               g.add_connection(cast, unpack)
-               g.add_connection(unpack, vtg, sink_ep="pixels")
-               g.add_connection(vtg, self.driver)
-               self.submodules += CompositeActor(g)
-
-               self.comb += [
-                       self.fi.trigger.eq(self._enable.storage),
-                       self.dma.generator.trigger.eq(self._enable.storage),
-               ]
-
-class Blender(PipelinedActor, AutoCSR):
-       def __init__(self, nimages, latency):
-               sink_layout = [("i"+str(i), pixel_layout) for i in range(nimages)]
-               self.sink = Sink(sink_layout)
-               self.source = Source(pixel_layout)
-               factors = []
-               for i in range(nimages):
-                       name = "f"+str(i)
-                       csr = CSRStorage(8, name=name)
-                       setattr(self, name, csr)
-                       factors.append(csr.storage)
-               PipelinedActor.__init__(self, latency)
-
-               ###
-
-               sink_registered = Record(sink_layout)
-               self.sync += If(self.pipe_ce, sink_registered.eq(self.sink.payload))
-
-               imgs = [getattr(sink_registered, "i"+str(i)) for i in range(nimages)]
-               outval = Record(pixel_layout)
-               for e in pixel_layout:
-                       name = e[0]
-                       inpixs = [getattr(img, name) for img in imgs]
-                       outpix = getattr(outval, name)
-                       for component in ["r", "g", "b"]:
-                               incomps = [getattr(pix, component) for pix in inpixs]
-                               outcomp = getattr(outpix, component)
-                               outcomp_full = Signal(19)
-                               self.comb += [
-                                       outcomp_full.eq(sum(incomp*factor for incomp, factor in zip(incomps, factors))),
-                                       If(outcomp_full[18],
-                                               outcomp.eq(2**10 - 1) # saturate on overflow
-                                       ).Else(
-                                               outcomp.eq(outcomp_full[8:18])
-                                       )
-                               ]
-
-               pipe_stmts = []
-               for i in range(latency-1):
-                       new_outval = Record(pixel_layout)
-                       pipe_stmts.append(new_outval.eq(outval))
-                       outval = new_outval
-               self.sync += If(self.pipe_ce, pipe_stmts)
-               self.comb += self.source.payload.eq(outval)
-
-class MixFramebuffer(Module, AutoCSR):
-       def __init__(self, pads_vga, pads_dvi, *lasmims, blender_latency=5):
-               pack_factor = lasmims[0].dw//(2*bpp)
-               packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
-               
-               self._enable = CSRStorage()
-               self.fi = FrameInitiator()
-               self.blender = Blender(len(lasmims), blender_latency)
-               self.driver = Driver(pads_vga, pads_dvi)
-               self.comb += self.fi.trigger.eq(self._enable.storage)
-
-               g = DataFlowGraph()
-               for n, lasmim in enumerate(lasmims):
-                       dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
-                       cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
-                       unpack = structuring.Unpack(pack_factor, pixel_layout)
-
-                       g.add_connection(dma, cast)
-                       g.add_connection(cast, unpack)
-                       g.add_connection(unpack, self.blender, sink_subr=["i"+str(n)])
-
-                       self.comb += dma.generator.trigger.eq(self._enable.storage)
-                       setattr(self, "dma"+str(n), dma)
-
-               vtg = VTG()
-               g.add_connection(self.fi, vtg, sink_ep="timing")
-               g.add_connection(self.blender, vtg, sink_ep="pixels")
-               g.add_connection(vtg, self.driver)
-               self.submodules += CompositeActor(g)
diff --git a/milkymist/framebuffer/dvi.py b/milkymist/framebuffer/dvi.py
deleted file mode 100644 (file)
index 9c08507..0000000
+++ /dev/null
@@ -1,219 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.misc import optree
-
-control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
-
-class Encoder(Module):
-       def __init__(self):
-               self.d = Signal(8)
-               self.c = Signal(2)
-               self.de = Signal()
-
-               self.out = Signal(10)
-
-               ###
-
-               # stage 1 - count number of 1s in data
-               d = Signal(8)
-               n1d = Signal(max=9)
-               self.sync += [
-                       n1d.eq(optree("+", [self.d[i] for i in range(8)])),
-                       d.eq(self.d)
-               ]
-
-               # stage 2 - add 9th bit
-               q_m = Signal(9)
-               q_m8_n = Signal()
-               self.comb += q_m8_n.eq((n1d > 4) | ((n1d == 4) & ~d[0]))
-               for i in range(8):
-                       if i:
-                               curval = curval ^ d[i] ^ q_m8_n 
-                       else:
-                               curval = d[0]           
-                       self.sync += q_m[i].eq(curval)
-               self.sync += q_m[8].eq(~q_m8_n)
-
-               # stage 3 - count number of 1s and 0s in q_m[:8]
-               q_m_r = Signal(9)
-               n0q_m = Signal(max=9)
-               n1q_m = Signal(max=9)
-               self.sync += [
-                       n0q_m.eq(optree("+", [~q_m[i] for i in range(8)])),
-                       n1q_m.eq(optree("+", [q_m[i] for i in range(8)])),
-                       q_m_r.eq(q_m)
-               ]
-
-               # stage 4 - final encoding
-               cnt = Signal((6, True))
-
-               s_c = self.c
-               s_de = self.de
-               for p in range(3):
-                       new_c = Signal(2)
-                       new_de = Signal()
-                       self.sync += new_c.eq(s_c), new_de.eq(s_de)
-                       s_c, s_de = new_c, new_de
-
-               self.sync += If(s_de,
-                               If((cnt == 0) | (n1q_m == n0q_m),
-                                       self.out[9].eq(~q_m_r[8]),
-                                       self.out[8].eq(q_m_r[8]),
-                                       If(q_m_r[8],
-                                               self.out[:8].eq(q_m_r[:8]),
-                                               cnt.eq(cnt + n1q_m - n0q_m)
-                                       ).Else(
-                                               self.out[:8].eq(~q_m_r[:8]),
-                                               cnt.eq(cnt + n0q_m - n1q_m)
-                                       )
-                               ).Else(
-                                       If((~cnt[5] & (n1q_m > n0q_m)) | (cnt[5] & (n0q_m > n1q_m)),
-                                               self.out[9].eq(1),
-                                               self.out[8].eq(q_m_r[8]),
-                                               self.out[:8].eq(~q_m_r[:8]),
-                                               cnt.eq(cnt + Cat(0, q_m_r[8]) + n0q_m - n1q_m)
-                                       ).Else(
-                                               self.out[9].eq(0),
-                                               self.out[8].eq(q_m_r[8]),
-                                               self.out[:8].eq(q_m_r[:8]),
-                                               cnt.eq(cnt - Cat(0, ~q_m_r[8]) + n1q_m - n0q_m)
-                                       )
-                               )
-                       ).Else(
-                               self.out.eq(Array(control_tokens)[s_c]),
-                               cnt.eq(0)
-                       )
-
-class _EncoderSerializer(Module):
-       def __init__(self, serdesstrobe, pad_p, pad_n):
-               self.submodules.encoder = RenameClockDomains(Encoder(), "pix")
-               self.d, self.c, self.de = self.encoder.d, self.encoder.c, self.encoder.de
-
-               ###
-
-               # 2X soft serialization
-               ed_2x = Signal(5)
-               self.sync.pix2x += ed_2x.eq(Mux(ClockSignal("pix"), self.encoder.out[:5], self.encoder.out[5:]))
-
-               # 5X hard serialization
-               cascade_di = Signal()
-               cascade_do = Signal()
-               cascade_ti = Signal()
-               cascade_to = Signal()
-               pad_se = Signal()
-               self.specials += [
-                       Instance("OSERDES2",
-                               p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
-                               p_SERDES_MODE="MASTER", p_OUTPUT_MODE="DIFFERENTIAL",
-
-                               o_OQ=pad_se,
-                               i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
-                               i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
-                               i_D1=ed_2x[4], i_D2=0, i_D3=0, i_D4=0,
-                               i_T1=0, i_T2=0, i_T3=0, i_T4=0,
-                               i_TRAIN=0, i_TCE=1,
-                               i_SHIFTIN1=1, i_SHIFTIN2=1,
-                               i_SHIFTIN3=cascade_do, i_SHIFTIN4=cascade_to,
-                               o_SHIFTOUT1=cascade_di, o_SHIFTOUT2=cascade_ti),
-                       Instance("OSERDES2",
-                               p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
-                               p_SERDES_MODE="SLAVE", p_OUTPUT_MODE="DIFFERENTIAL",
-
-                               i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
-                               i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
-                               i_D1=ed_2x[0], i_D2=ed_2x[1], i_D3=ed_2x[2], i_D4=ed_2x[3],
-                               i_T1=0, i_T2=0, i_T3=0, i_T4=0,
-                               i_TRAIN=0, i_TCE=1,
-                               i_SHIFTIN1=cascade_di, i_SHIFTIN2=cascade_ti,
-                               i_SHIFTIN3=1, i_SHIFTIN4=1,
-                               o_SHIFTOUT3=cascade_do, o_SHIFTOUT4=cascade_to),
-                       Instance("OBUFDS", i_I=pad_se, o_O=pad_p, o_OB=pad_n)
-               ]
-
-
-class PHY(Module):
-       def __init__(self, serdesstrobe, pads):
-               self.hsync = Signal()
-               self.vsync = Signal()
-               self.de = Signal()
-               self.r = Signal(8)
-               self.g = Signal(8)
-               self.b = Signal(8)
-
-               ###
-
-               self.submodules.es0 = _EncoderSerializer(serdesstrobe, pads.data0_p, pads.data0_n)
-               self.submodules.es1 = _EncoderSerializer(serdesstrobe, pads.data1_p, pads.data1_n)
-               self.submodules.es2 = _EncoderSerializer(serdesstrobe, pads.data2_p, pads.data2_n)
-               self.comb += [
-                       self.es0.d.eq(self.r),
-                       self.es1.d.eq(self.g),
-                       self.es2.d.eq(self.b),
-                       self.es0.c.eq(Cat(self.hsync, self.vsync)),
-                       self.es1.c.eq(0),
-                       self.es2.c.eq(0),
-                       self.es0.de.eq(self.de),
-                       self.es1.de.eq(self.de),
-                       self.es2.de.eq(self.de),
-               ]
-
-class _EncoderTB(Module):
-       def __init__(self, inputs):
-               self.outs = []
-               self._iter_inputs = iter(inputs)
-               self._end_cycle = None
-               self.submodules.dut = Encoder()
-               self.comb += self.dut.de.eq(1)
-
-       def do_simulation(self, s):
-               if self._end_cycle is None:
-                       try:
-                               nv = next(self._iter_inputs)
-                       except StopIteration:
-                               self._end_cycle = s.cycle_counter + 4
-                       else:
-                               s.wr(self.dut.d, nv)
-               if s.cycle_counter == self._end_cycle:
-                       s.interrupt = True
-               if s.cycle_counter > 4:
-                       self.outs.append(s.rd(self.dut.out))
-
-def _bit(i, n):
-       return (i >> n) & 1
-
-def _decode_tmds(b):
-       try:
-               c = control_tokens.index(b)
-               de = False
-       except ValueError:
-               c = 0
-               de = True
-       vsync = bool(c & 2)
-       hsync = bool(c & 1)
-
-       value = _bit(b, 0) ^ _bit(b, 9)
-       for i in range(1, 8):
-               value |= (_bit(b, i) ^ _bit(b, i-1) ^ (~_bit(b, 8) & 1)) << i
-
-       return de, hsync, vsync, value
-
-if __name__ == "__main__":
-       from migen.sim.generic import Simulator
-       from random import Random
-       
-       rng = Random(788)
-       test_list = [rng.randrange(256) for i in range(500)]
-       tb = _EncoderTB(test_list)
-       Simulator(tb).run()
-
-       check = [_decode_tmds(out)[3] for out in tb.outs]
-       assert(check == test_list)
-       
-       nb0 = 0
-       nb1 = 0
-       for out in tb.outs:
-               for i in range(10):
-                       if _bit(out, i):
-                               nb1 += 1
-                       else:
-                               nb0 += 1
-       print("0/1: {}/{} ({:.2f})".format(nb0, nb1, nb0/nb1))
diff --git a/milkymist/framebuffer/format.py b/milkymist/framebuffer/format.py
deleted file mode 100644 (file)
index 7e42245..0000000
+++ /dev/null
@@ -1,113 +0,0 @@
-from migen.fhdl.std import *
-from migen.flow.actor import *
-from migen.bank.description import CSRStorage
-from migen.actorlib import spi
-
-_hbits = 11
-_vbits = 12
-
-bpp = 32
-bpc = 10
-pixel_layout_s = [
-       ("pad", bpp-3*bpc),
-       ("r", bpc),
-       ("g", bpc),
-       ("b", bpc)
-]
-pixel_layout = [
-       ("p0", pixel_layout_s),
-       ("p1", pixel_layout_s)
-]
-
-bpc_phy = 8
-phy_layout_s = [
-       ("r", bpc_phy),
-       ("g", bpc_phy),
-       ("b", bpc_phy)
-]
-phy_layout = [
-       ("hsync", 1),
-       ("vsync", 1),
-       ("de", 1),
-       ("p0", phy_layout_s),
-       ("p1", phy_layout_s)
-]
-
-class FrameInitiator(spi.SingleGenerator):
-       def __init__(self):
-               layout = [
-                       ("hres", _hbits, 640, 1),
-                       ("hsync_start", _hbits, 656, 1),
-                       ("hsync_end", _hbits, 752, 1),
-                       ("hscan", _hbits, 800, 1),
-                       
-                       ("vres", _vbits, 480),
-                       ("vsync_start", _vbits, 492),
-                       ("vsync_end", _vbits, 494),
-                       ("vscan", _vbits, 525)
-               ]
-               spi.SingleGenerator.__init__(self, layout, spi.MODE_EXTERNAL)
-
-class VTG(Module):
-       def __init__(self):
-               self.timing = Sink([
-                               ("hres", _hbits),
-                               ("hsync_start", _hbits),
-                               ("hsync_end", _hbits),
-                               ("hscan", _hbits),
-                               ("vres", _vbits),
-                               ("vsync_start", _vbits),
-                               ("vsync_end", _vbits),
-                               ("vscan", _vbits)])
-               self.pixels = Sink(pixel_layout)
-               self.phy = Source(phy_layout)
-               self.busy = Signal()
-
-               hactive = Signal()
-               vactive = Signal()
-               active = Signal()
-               
-               generate_en = Signal()
-               hcounter = Signal(_hbits)
-               vcounter = Signal(_vbits)
-               
-               skip = bpc - bpc_phy
-               self.comb += [
-                       active.eq(hactive & vactive),
-                       If(active,
-                               [getattr(getattr(self.phy.payload, p), c).eq(getattr(getattr(self.pixels.payload, p), c)[skip:])
-                                       for p in ["p0", "p1"] for c in ["r", "g", "b"]],
-                               self.phy.payload.de.eq(1)
-                       ),
-                       
-                       generate_en.eq(self.timing.stb & (~active | self.pixels.stb)),
-                       self.pixels.ack.eq(self.phy.ack & active),
-                       self.phy.stb.eq(generate_en),
-                       self.busy.eq(generate_en)
-               ]
-               tp = self.timing.payload
-               self.sync += [
-                       self.timing.ack.eq(0),
-                       If(generate_en & self.phy.ack,
-                               hcounter.eq(hcounter + 1),
-                       
-                               If(hcounter == 0, hactive.eq(1)),
-                               If(hcounter == tp.hres, hactive.eq(0)),
-                               If(hcounter == tp.hsync_start, self.phy.payload.hsync.eq(1)),
-                               If(hcounter == tp.hsync_end, self.phy.payload.hsync.eq(0)),
-                               If(hcounter == tp.hscan,
-                                       hcounter.eq(0),
-                                       If(vcounter == tp.vscan,
-                                               vcounter.eq(0),
-                                               self.timing.ack.eq(1)
-                                       ).Else(
-                                               vcounter.eq(vcounter + 1)
-                                       )
-                               ),
-                               
-                               If(vcounter == 0, vactive.eq(1)),
-                               If(vcounter == tp.vres, vactive.eq(0)),
-                               If(vcounter == tp.vsync_start, self.phy.payload.vsync.eq(1)),
-                               If(vcounter == tp.vsync_end, self.phy.payload.vsync.eq(0))
-                       )
-               ]
diff --git a/milkymist/framebuffer/phy.py b/milkymist/framebuffer/phy.py
deleted file mode 100644 (file)
index 0fbc65d..0000000
+++ /dev/null
@@ -1,197 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.fifo import AsyncFIFO
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-from migen.flow.actor import *
-
-from milkymist.framebuffer.format import bpc_phy, phy_layout
-from milkymist.framebuffer import dvi
-
-class _FIFO(Module):
-       def __init__(self):
-               self.phy = Sink(phy_layout)
-               self.busy = Signal()
-               
-               self.pix_hsync = Signal()
-               self.pix_vsync = Signal()
-               self.pix_de = Signal()
-               self.pix_r = Signal(bpc_phy)
-               self.pix_g = Signal(bpc_phy)
-               self.pix_b = Signal(bpc_phy)
-       
-               ###
-
-               fifo = RenameClockDomains(AsyncFIFO(phy_layout, 512),
-                       {"write": "sys", "read": "pix"})
-               self.submodules += fifo
-               self.comb += [
-                       self.phy.ack.eq(fifo.writable),
-                       fifo.we.eq(self.phy.stb),
-                       fifo.din.eq(self.phy.payload),
-                       self.busy.eq(0)
-               ]
-
-               pix_parity = Signal()
-               self.sync.pix += [
-                       pix_parity.eq(~pix_parity),
-                       self.pix_hsync.eq(fifo.dout.hsync),
-                       self.pix_vsync.eq(fifo.dout.vsync),
-                       self.pix_de.eq(fifo.dout.de),
-                       If(pix_parity,
-                               self.pix_r.eq(fifo.dout.p1.r),
-                               self.pix_g.eq(fifo.dout.p1.g),
-                               self.pix_b.eq(fifo.dout.p1.b)
-                       ).Else(
-                               self.pix_r.eq(fifo.dout.p0.r),
-                               self.pix_g.eq(fifo.dout.p0.g),
-                               self.pix_b.eq(fifo.dout.p0.b)
-                       )
-               ]
-               self.comb += fifo.re.eq(pix_parity)
-
-# This assumes a 50MHz base clock
-class _Clocking(Module, AutoCSR):
-       def __init__(self, pads_vga, pads_dvi):
-               self._r_cmd_data = CSRStorage(10)
-               self._r_send_cmd_data = CSR()
-               self._r_send_go = CSR()
-               self._r_status = CSRStatus(4)
-
-               self.clock_domains.cd_pix = ClockDomain(reset_less=True)
-               if pads_dvi is not None:
-                       self.clock_domains.cd_pix2x = ClockDomain(reset_less=True)
-                       self.clock_domains.cd_pix10x = ClockDomain(reset_less=True)
-                       self.serdesstrobe = Signal()
-
-               ###
-
-               # Generate 1x pixel clock
-               clk_pix_unbuffered = Signal()
-               pix_progdata = Signal()
-               pix_progen = Signal()
-               pix_progdone = Signal()
-               pix_locked = Signal()
-               self.specials += Instance("DCM_CLKGEN",
-                       p_CLKFXDV_DIVIDE=2, p_CLKFX_DIVIDE=4, p_CLKFX_MD_MAX=1.0, p_CLKFX_MULTIPLY=2,
-                       p_CLKIN_PERIOD=20.0, p_SPREAD_SPECTRUM="NONE", p_STARTUP_WAIT="FALSE",
-               
-                       i_CLKIN=ClockSignal("base50"), o_CLKFX=clk_pix_unbuffered,
-                       i_PROGCLK=ClockSignal(), i_PROGDATA=pix_progdata, i_PROGEN=pix_progen,
-                       o_PROGDONE=pix_progdone, o_LOCKED=pix_locked,
-                       i_FREEZEDCM=0, i_RST=ResetSignal())
-
-               remaining_bits = Signal(max=11)
-               transmitting = Signal()
-               self.comb += transmitting.eq(remaining_bits != 0)
-               sr = Signal(10)
-               self.sync += [
-                       If(self._r_send_cmd_data.re,
-                               remaining_bits.eq(10),
-                               sr.eq(self._r_cmd_data.storage)
-                       ).Elif(transmitting,
-                               remaining_bits.eq(remaining_bits - 1),
-                               sr.eq(sr[1:])
-                       )
-               ]
-               self.comb += [
-                       pix_progdata.eq(transmitting & sr[0]),
-                       pix_progen.eq(transmitting | self._r_send_go.re)
-               ]
-
-               # enforce gap between commands
-               busy_counter = Signal(max=14)
-               busy = Signal()
-               self.comb += busy.eq(busy_counter != 0)
-               self.sync += If(self._r_send_cmd_data.re,
-                               busy_counter.eq(13)
-                       ).Elif(busy,
-                               busy_counter.eq(busy_counter - 1)
-                       )
-
-               mult_locked = Signal()
-               self.comb += self._r_status.status.eq(Cat(busy, pix_progdone, pix_locked, mult_locked))
-
-               # Clock multiplication and buffering
-               if pads_dvi is None:
-                       # Just buffer 1x pixel clock
-                       self.specials += Instance("BUFG", i_I=clk_pix_unbuffered, o_O=self.cd_pix.clk)
-                       self.comb += mult_locked.eq(pix_locked)
-               else:
-                       # Route unbuffered 1x pixel clock to PLL
-                       # Generate 1x, 2x and 10x IO pixel clocks
-                       clkfbout = Signal()
-                       pll_locked = Signal()
-                       pll_clk0 = Signal()
-                       pll_clk1 = Signal()
-                       pll_clk2 = Signal()
-                       locked_async = Signal()
-                       self.specials += [
-                               Instance("PLL_BASE",
-                                       p_CLKIN_PERIOD=26.7,
-                                       p_CLKFBOUT_MULT=20,
-                                       p_CLKOUT0_DIVIDE=2,  # pix10x
-                                       p_CLKOUT1_DIVIDE=10, # pix2x
-                                       p_CLKOUT2_DIVIDE=20, # pix
-                                       p_COMPENSATION="INTERNAL",
-                                       
-                                       i_CLKIN=clk_pix_unbuffered,
-                                       o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
-                                       o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
-                                       o_LOCKED=pll_locked, i_RST=~pix_locked),
-                               Instance("BUFPLL", p_DIVIDE=5,
-                                       i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
-                                       o_IOCLK=self.cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
-                               Instance("BUFG", i_I=pll_clk1, o_O=self.cd_pix2x.clk),
-                               Instance("BUFG", name="dviout_pix_bufg", i_I=pll_clk2, o_O=self.cd_pix.clk),
-                               MultiReg(locked_async, mult_locked, "sys")
-                       ]
-
-               # Drive VGA/DVI clock pads
-               if pads_vga is not None:
-                       self.specials += Instance("ODDR2",
-                               p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
-                               o_Q=pads_vga.clk,
-                               i_C0=ClockSignal("pix"),
-                               i_C1=~ClockSignal("pix"),
-                               i_CE=1, i_D0=1, i_D1=0,
-                               i_R=0, i_S=0)
-               if pads_dvi is not None:
-                       dvi_clk_se = Signal()
-                       self.specials += Instance("ODDR2",
-                               p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
-                               o_Q=dvi_clk_se,
-                               i_C0=ClockSignal("pix"),
-                               i_C1=~ClockSignal("pix"),
-                               i_CE=1, i_D0=1, i_D1=0,
-                               i_R=0, i_S=0)
-                       self.specials += Instance("OBUFDS", i_I=dvi_clk_se,
-                               o_O=pads_dvi.clk_p, o_OB=pads_dvi.clk_n)
-
-class Driver(Module, AutoCSR):
-       def __init__(self, pads_vga, pads_dvi):
-               fifo = _FIFO()
-               self.submodules += fifo
-               self.phy = fifo.phy
-               self.busy = fifo.busy
-
-               self.submodules.clocking = _Clocking(pads_vga, pads_dvi)
-
-               if pads_vga is not None:
-                       self.comb += [
-                               pads_vga.hsync_n.eq(~fifo.pix_hsync),
-                               pads_vga.vsync_n.eq(~fifo.pix_vsync),
-                               pads_vga.r.eq(fifo.pix_r),
-                               pads_vga.g.eq(fifo.pix_g),
-                               pads_vga.b.eq(fifo.pix_b),
-                               pads_vga.psave_n.eq(1)
-                       ]
-               if pads_dvi is not None:
-                       self.submodules.dvi_phy = dvi.PHY(self.clocking.serdesstrobe, pads_dvi)
-                       self.comb += [
-                               self.dvi_phy.hsync.eq(fifo.pix_hsync),
-                               self.dvi_phy.vsync.eq(fifo.pix_vsync),
-                               self.dvi_phy.de.eq(fifo.pix_de),
-                               self.dvi_phy.r.eq(fifo.pix_r),
-                               self.dvi_phy.g.eq(fifo.pix_g),
-                               self.dvi_phy.b.eq(fifo.pix_b)
-                       ]
diff --git a/milkymist/gpio/__init__.py b/milkymist/gpio/__init__.py
deleted file mode 100644 (file)
index d02332e..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-
-class GPIOIn(Module, AutoCSR):
-       def __init__(self, signal):
-               self._r_in = CSRStatus(flen(signal))
-               self.specials += MultiReg(signal, self._r_in.status)
-
-class GPIOOut(Module, AutoCSR):
-       def __init__(self, signal):
-               self._r_out = CSRStorage(flen(signal))
-               self.comb += signal.eq(self._r_out.storage)
-
-class Blinker(Module):
-       def __init__(self, signal, divbits=26):
-               counter = Signal(divbits)
-               self.comb += signal.eq(counter[divbits-1])
-               self.sync += counter.eq(counter + 1)
diff --git a/milkymist/identifier/__init__.py b/milkymist/identifier/__init__.py
deleted file mode 100644 (file)
index ca792fd..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-import re
-
-from migen.fhdl.std import *
-from migen.bank.description import *
-
-def encode_version(version):
-       match = re.match("(\d+)\.(\d+)(\.(\d+))?(rc(\d+))?", version, re.IGNORECASE)
-       r = (int(match.group(1)) << 12) | (int(match.group(2)) << 8)
-       subminor = match.group(4)
-       rc = match.group(6)
-       if subminor:
-               r |= int(subminor) << 4
-       if rc:
-               r |= int(rc)
-       return r
-
-class Identifier(Module, AutoCSR):
-       def __init__(self, sysid, version, frequency):
-               self._r_sysid = CSRStatus(16)
-               self._r_version = CSRStatus(16)
-               self._r_frequency = CSRStatus(32)
-               
-               ###
-
-               self.comb += [
-                       self._r_sysid.status.eq(sysid),
-                       self._r_version.status.eq(encode_version(version)),
-                       self._r_frequency.status.eq(frequency)
-               ]
diff --git a/milkymist/lasmicon/__init__.py b/milkymist/lasmicon/__init__.py
deleted file mode 100644 (file)
index 2e32d68..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-from collections import namedtuple
-
-from migen.fhdl.std import *
-from migen.bus import dfi, lasmibus
-
-from milkymist.lasmicon.refresher import *
-from milkymist.lasmicon.bankmachine import *
-from milkymist.lasmicon.multiplexer import *
-
-PhySettings = namedtuple("PhySettings", "memtype dfi_d nphases rdphase wrphase rdcmdphase wrcmdphase cl read_latency write_latency")
-
-class GeomSettings(namedtuple("_GeomSettings", "bank_a row_a col_a")):
-       def __init__(self, *args, **kwargs):
-               self.mux_a = max(self.row_a, self.col_a)
-
-TimingSettings = namedtuple("TimingSettings", "tRP tRCD tWR tWTR tREFI tRFC" \
-       " req_queue_size read_time write_time")
-
-class LASMIcon(Module):
-       def __init__(self, phy_settings, geom_settings, timing_settings):
-               if phy_settings.memtype in ["SDR"]:
-                       burst_length = phy_settings.nphases*1 # command multiplication*SDR
-               elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
-                       burst_length = phy_settings.nphases*2 # command multiplication*DDR
-               address_align = log2_int(burst_length)
-
-               self.dfi = dfi.Interface(geom_settings.mux_a,
-                       geom_settings.bank_a,
-                       phy_settings.dfi_d,
-                       phy_settings.nphases)
-               self.lasmic = lasmibus.Interface(
-                       aw=geom_settings.row_a + geom_settings.col_a - address_align,
-                       dw=phy_settings.dfi_d*phy_settings.nphases,
-                       nbanks=2**geom_settings.bank_a,
-                       req_queue_size=timing_settings.req_queue_size,
-                       read_latency=phy_settings.read_latency+1,
-                       write_latency=phy_settings.write_latency+1)
-               self.nrowbits = geom_settings.col_a - address_align
-       
-               ###
-
-               self.submodules.refresher = Refresher(geom_settings.mux_a, geom_settings.bank_a,
-                       timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC)
-               self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, address_align, i,
-                               getattr(self.lasmic, "bank"+str(i)))
-                       for i in range(2**geom_settings.bank_a)]
-               self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings,
-                       self.bank_machines, self.refresher,
-                       self.dfi, self.lasmic)
-
-       def get_csrs(self):
-               return self.multiplexer.get_csrs()
diff --git a/milkymist/lasmicon/bankmachine.py b/milkymist/lasmicon/bankmachine.py
deleted file mode 100644 (file)
index 6db44d1..0000000
+++ /dev/null
@@ -1,144 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.roundrobin import *
-from migen.genlib.fsm import FSM, NextState
-from migen.genlib.misc import optree
-from migen.genlib.fifo import SyncFIFO
-
-from milkymist.lasmicon.multiplexer import *
-
-class _AddressSlicer:
-       def __init__(self, col_a, address_align):
-               self.col_a = col_a
-               self.address_align = address_align
-       
-       def row(self, address):
-               split = self.col_a - self.address_align
-               if isinstance(address, int):
-                       return address >> split
-               else:
-                       return address[split:]
-               
-       def col(self, address):
-               split = self.col_a - self.address_align
-               if isinstance(address, int):
-                       return (address & (2**split - 1)) << self.address_align
-               else:
-                       return Cat(Replicate(0, self.address_align), address[:split])
-       
-class BankMachine(Module):
-       def __init__(self, geom_settings, timing_settings, address_align, bankn, req):
-               self.refresh_req = Signal()
-               self.refresh_gnt = Signal()
-               self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a)
-
-               ###
-
-               # Request FIFO
-               self.submodules.req_fifo = SyncFIFO([("we", 1), ("adr", flen(req.adr))], timing_settings.req_queue_size)
-               self.comb += [
-                       self.req_fifo.din.we.eq(req.we),
-                       self.req_fifo.din.adr.eq(req.adr),
-                       self.req_fifo.we.eq(req.stb),
-                       req.req_ack.eq(self.req_fifo.writable),
-
-                       self.req_fifo.re.eq(req.dat_ack),
-                       req.lock.eq(self.req_fifo.readable)
-               ]
-               reqf = self.req_fifo.dout
-
-               slicer = _AddressSlicer(geom_settings.col_a, address_align)
-               
-               # Row tracking
-               has_openrow = Signal()
-               openrow = Signal(geom_settings.row_a)
-               hit = Signal()
-               self.comb += hit.eq(openrow == slicer.row(reqf.adr))
-               track_open = Signal()
-               track_close = Signal()
-               self.sync += [
-                       If(track_open,
-                               has_openrow.eq(1),
-                               openrow.eq(slicer.row(reqf.adr))
-                       ),
-                       If(track_close,
-                               has_openrow.eq(0)
-                       )
-               ]
-               
-               # Address generation
-               s_row_adr = Signal()
-               self.comb += [
-                       self.cmd.ba.eq(bankn),
-                       If(s_row_adr,
-                               self.cmd.a.eq(slicer.row(reqf.adr))
-                       ).Else(
-                               self.cmd.a.eq(slicer.col(reqf.adr))
-                       )
-               ]
-               
-               # Respect write-to-precharge specification
-               precharge_ok = Signal()
-               t_unsafe_precharge = 2 + timing_settings.tWR - 1
-               unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
-               self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
-               self.sync += [
-                       If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
-                               unsafe_precharge_count.eq(t_unsafe_precharge)
-                       ).Elif(~precharge_ok,
-                               unsafe_precharge_count.eq(unsafe_precharge_count-1)
-                       )
-               ]
-               
-               # Control and command generation FSM
-               fsm = FSM()
-               self.submodules += fsm
-               fsm.act("REGULAR",
-                       If(self.refresh_req,
-                               NextState("REFRESH")
-                       ).Elif(self.req_fifo.readable,
-                               If(has_openrow,
-                                       If(hit,
-                                               # NB: write-to-read specification is enforced by multiplexer
-                                               self.cmd.stb.eq(1),
-                                               req.dat_ack.eq(self.cmd.ack),
-                                               self.cmd.is_read.eq(~reqf.we),
-                                               self.cmd.is_write.eq(reqf.we),
-                                               self.cmd.cas_n.eq(0),
-                                               self.cmd.we_n.eq(~reqf.we)
-                                       ).Else(
-                                               NextState("PRECHARGE")
-                                       )
-                               ).Else(
-                                       NextState("ACTIVATE")
-                               )
-                       )
-               )
-               fsm.act("PRECHARGE",
-                       # Notes:
-                       # 1. we are presenting the column address, A10 is always low
-                       # 2. since we always go to the ACTIVATE state, we do not need
-                       # to assert track_close.
-                       If(precharge_ok,
-                               self.cmd.stb.eq(1),
-                               If(self.cmd.ack, NextState("TRP")),
-                               self.cmd.ras_n.eq(0),
-                               self.cmd.we_n.eq(0),
-                               self.cmd.is_cmd.eq(1)
-                       )
-               )
-               fsm.act("ACTIVATE",
-                       s_row_adr.eq(1),
-                       track_open.eq(1),
-                       self.cmd.stb.eq(1),
-                       self.cmd.is_cmd.eq(1),
-                       If(self.cmd.ack, NextState("TRCD")),
-                       self.cmd.ras_n.eq(0)
-               )
-               fsm.act("REFRESH",
-                       self.refresh_gnt.eq(precharge_ok),
-                       track_close.eq(1),
-                       self.cmd.is_cmd.eq(1),
-                       If(~self.refresh_req, NextState("REGULAR"))
-               )
-               fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
-               fsm.delayed_enter("TRCD", "REGULAR", timing_settings.tRCD-1)
diff --git a/milkymist/lasmicon/multiplexer.py b/milkymist/lasmicon/multiplexer.py
deleted file mode 100644 (file)
index 2f023ac..0000000
+++ /dev/null
@@ -1,210 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.roundrobin import *
-from migen.genlib.misc import optree
-from migen.genlib.fsm import FSM, NextState
-from migen.bank.description import AutoCSR
-
-from milkymist.lasmicon.perf import Bandwidth
-
-class CommandRequest:
-       def __init__(self, a, ba):
-               self.a = Signal(a)
-               self.ba = Signal(ba)
-               self.cas_n = Signal(reset=1)
-               self.ras_n = Signal(reset=1)
-               self.we_n = Signal(reset=1)
-
-class CommandRequestRW(CommandRequest):
-       def __init__(self, a, ba):
-               CommandRequest.__init__(self, a, ba)
-               self.stb = Signal()
-               self.ack = Signal()
-               self.is_cmd = Signal()
-               self.is_read = Signal()
-               self.is_write = Signal()
-
-class _CommandChooser(Module):
-       def __init__(self, requests):
-               self.want_reads = Signal()
-               self.want_writes = Signal()
-               self.want_cmds = Signal()
-               # NB: cas_n/ras_n/we_n are 1 when stb is inactive
-               self.cmd = CommandRequestRW(flen(requests[0].a), flen(requests[0].ba))
-       
-               ###
-
-               rr = RoundRobin(len(requests), SP_CE)
-               self.submodules += rr
-               
-               self.comb += [rr.request[i].eq(req.stb & ((req.is_cmd & self.want_cmds) | ((req.is_read == self.want_reads) | (req.is_write == self.want_writes))))
-                       for i, req in enumerate(requests)]
-               
-               stb = Signal()
-               self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
-               for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
-                       choices = Array(getattr(req, name) for req in requests)
-                       self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
-               for name in ["cas_n", "ras_n", "we_n"]:
-                       # we should only assert those signals when stb is 1
-                       choices = Array(getattr(req, name) for req in requests)
-                       self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
-               self.comb += self.cmd.stb.eq(stb \
-                       & ((self.cmd.is_cmd & self.want_cmds) | ((self.cmd.is_read == self.want_reads) \
-                       & (self.cmd.is_write == self.want_writes))))
-               
-               self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
-                       for i, req in enumerate(requests)]
-               self.comb += rr.ce.eq(self.cmd.ack)
-
-class _Steerer(Module):
-       def __init__(self, commands, dfi):
-               ncmd = len(commands)
-               nph = len(dfi.phases)
-               self.sel = [Signal(max=ncmd) for i in range(nph)]
-       
-               ###
-       
-               def stb_and(cmd, attr):
-                       if not hasattr(cmd, "stb"):
-                               return 0
-                       else:
-                               return cmd.stb & getattr(cmd, attr)
-               for phase, sel in zip(dfi.phases, self.sel):
-                       self.comb += [
-                               phase.cke.eq(1),
-                               phase.cs_n.eq(0)
-                       ]
-                       self.sync += [
-                               phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
-                               phase.bank.eq(Array(cmd.ba for cmd in commands)[sel]),
-                               phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
-                               phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
-                               phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
-                               phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
-                               phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
-                       ]
-
-class Multiplexer(Module, AutoCSR):
-       def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
-               assert(phy_settings.nphases == len(dfi.phases))
-       
-               # Command choosing
-               requests = [bm.cmd for bm in bank_machines]
-               choose_cmd = _CommandChooser(requests)
-               choose_req = _CommandChooser(requests)
-               self.comb += [
-                       choose_cmd.want_reads.eq(0),
-                       choose_cmd.want_writes.eq(0)
-               ]
-               if phy_settings.nphases == 1:
-                       self.comb += [
-                               choose_cmd.want_cmds.eq(1),
-                               choose_req.want_cmds.eq(1)
-                       ]       
-               self.submodules += choose_cmd, choose_req
-               
-               # Command steering
-               nop = CommandRequest(geom_settings.mux_a, geom_settings.bank_a)
-               commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
-               (STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
-               steerer = _Steerer(commands, dfi)
-               self.submodules += steerer
-               
-               # Read/write turnaround
-               read_available = Signal()
-               write_available = Signal()
-               self.comb += [
-                       read_available.eq(optree("|", [req.stb & req.is_read for req in requests])),
-                       write_available.eq(optree("|", [req.stb & req.is_write for req in requests]))
-               ]
-               
-               def anti_starvation(timeout):
-                       en = Signal()
-                       max_time = Signal()
-                       if timeout:
-                               t = timeout - 1
-                               time = Signal(max=t+1)
-                               self.comb += max_time.eq(time == 0)
-                               self.sync += If(~en,
-                                               time.eq(t)
-                                       ).Elif(~max_time,
-                                               time.eq(time - 1)
-                                       )
-                       else:
-                               self.comb += max_time.eq(0)
-                       return en, max_time
-               read_time_en, max_read_time = anti_starvation(timing_settings.read_time)
-               write_time_en, max_write_time = anti_starvation(timing_settings.write_time)
-               
-               # Refresh
-               self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
-               go_to_refresh = Signal()
-               self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines]))
-               
-               # Datapath
-               all_rddata = [p.rddata for p in dfi.phases]
-               all_wrdata = [p.wrdata for p in dfi.phases]
-               all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
-               self.comb += [
-                       lasmic.dat_r.eq(Cat(*all_rddata)),
-                       Cat(*all_wrdata).eq(lasmic.dat_w),
-                       Cat(*all_wrdata_mask).eq(~lasmic.dat_we)
-               ]
-               
-               # Control FSM
-               fsm = FSM()
-               self.submodules += fsm
-               
-               def steerer_sel(steerer, phy_settings, r_w_n):
-                       r = []
-                       for i in range(phy_settings.nphases):
-                               s = steerer.sel[i].eq(STEER_NOP)
-                               if r_w_n == "read":
-                                       if i == phy_settings.rdphase:
-                                               s = steerer.sel[i].eq(STEER_REQ)
-                                       elif i == phy_settings.rdcmdphase:
-                                               s = steerer.sel[i].eq(STEER_CMD)
-                               elif r_w_n == "write":
-                                       if i == phy_settings.wrphase:
-                                               s = steerer.sel[i].eq(STEER_REQ)
-                                       elif i == phy_settings.wrcmdphase:
-                                               s = steerer.sel[i].eq(STEER_CMD)
-                               else:
-                                       raise ValueError
-                               r.append(s)
-                       return r
-
-               fsm.act("READ",
-                       read_time_en.eq(1),
-                       choose_req.want_reads.eq(1),
-                       choose_cmd.cmd.ack.eq(1),
-                       choose_req.cmd.ack.eq(1),
-                       steerer_sel(steerer, phy_settings, "read"),
-                       If(write_available,
-                               # TODO: switch only after several cycles of ~read_available?
-                               If(~read_available | max_read_time, NextState("RTW"))
-                       ),
-                       If(go_to_refresh, NextState("REFRESH"))
-               )
-               fsm.act("WRITE",
-                       write_time_en.eq(1),
-                       choose_req.want_writes.eq(1),
-                       choose_cmd.cmd.ack.eq(1),
-                       choose_req.cmd.ack.eq(1),
-                       steerer_sel(steerer, phy_settings, "write"),
-                       If(read_available,
-                               If(~write_available | max_write_time, NextState("WTR"))
-                       ),
-                       If(go_to_refresh, NextState("REFRESH"))
-               )
-               fsm.act("REFRESH",
-                       steerer.sel[0].eq(STEER_REFRESH),
-                       If(~refresher.req, NextState("READ"))
-               )
-               fsm.delayed_enter("RTW", "WRITE", phy_settings.read_latency-1) # FIXME: reduce this, actual limit is around (cl+1)/nphases
-               fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
-               # FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
-               fsm.finalize()
-               self.comb += refresher.ack.eq(fsm.state == fsm.encoding["REFRESH"])
-
-               self.submodules.bandwidth = Bandwidth(choose_req.cmd)
diff --git a/milkymist/lasmicon/perf.py b/milkymist/lasmicon/perf.py
deleted file mode 100644 (file)
index ec09c79..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-from migen.fhdl.std import *
-from migen.bank.description import *
-
-class Bandwidth(Module, AutoCSR):
-       def __init__(self, cmd, period_bits=24):
-               self._r_update = CSR()
-               self._r_nreads = CSRStatus(period_bits)
-               self._r_nwrites = CSRStatus(period_bits)
-
-               ###
-
-               cmd_stb = Signal()
-               cmd_ack = Signal()
-               cmd_is_read = Signal()
-               cmd_is_write = Signal()
-               self.sync += [
-                       cmd_stb.eq(cmd.stb),
-                       cmd_ack.eq(cmd.ack),
-                       cmd_is_read.eq(cmd.is_read),
-                       cmd_is_write.eq(cmd.is_write)
-               ]
-
-               counter = Signal(period_bits)
-               period = Signal()
-               nreads = Signal(period_bits)
-               nwrites = Signal(period_bits)
-               nreads_r = Signal(period_bits)
-               nwrites_r = Signal(period_bits)
-               self.sync += [
-                       Cat(counter, period).eq(counter + 1),
-                       If(period,
-                               nreads_r.eq(nreads),
-                               nwrites_r.eq(nwrites),
-                               nreads.eq(0),
-                               nwrites.eq(0)
-                       ).Elif(cmd_stb & cmd_ack,
-                               If(cmd_is_read, nreads.eq(nreads + 1)),
-                               If(cmd_is_write, nwrites.eq(nwrites + 1)),
-                       ),
-                       If(self._r_update.re,
-                               self._r_nreads.status.eq(nreads_r),
-                               self._r_nwrites.status.eq(nwrites_r)
-                       )
-               ]
diff --git a/milkymist/lasmicon/refresher.py b/milkymist/lasmicon/refresher.py
deleted file mode 100644 (file)
index d22271c..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.misc import timeline
-from migen.genlib.fsm import FSM
-
-from milkymist.lasmicon.multiplexer import *
-
-class Refresher(Module):
-       def __init__(self, a, ba, tRP, tREFI, tRFC):
-               self.req = Signal()
-               self.ack = Signal() # 1st command 1 cycle after assertion of ack
-               self.cmd = CommandRequest(a, ba)
-       
-               ###
-
-               # Refresh sequence generator:
-               # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
-               seq_start = Signal()
-               seq_done = Signal()
-               self.sync += [
-                       self.cmd.a.eq(2**10),
-                       self.cmd.ba.eq(0),
-                       self.cmd.cas_n.eq(1),
-                       self.cmd.ras_n.eq(1),
-                       self.cmd.we_n.eq(1),
-                       seq_done.eq(0)
-               ]
-               self.sync += timeline(seq_start, [
-                       (1, [
-                               self.cmd.ras_n.eq(0),
-                               self.cmd.we_n.eq(0)
-                       ]),
-                       (1+tRP, [
-                               self.cmd.cas_n.eq(0),
-                               self.cmd.ras_n.eq(0)
-                       ]),
-                       (1+tRP+tRFC, [
-                               seq_done.eq(1)
-                       ])
-               ])
-               
-               # Periodic refresh counter
-               counter = Signal(max=tREFI)
-               start = Signal()
-               self.sync += [
-                       start.eq(0),
-                       If(counter == 0,
-                               start.eq(1),
-                               counter.eq(tREFI - 1)
-                       ).Else(
-                               counter.eq(counter - 1)
-                       )
-               ]
-               
-               # Control FSM
-               fsm = FSM()
-               self.submodules += fsm
-               fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
-               fsm.act("WAIT_GRANT",
-                       self.req.eq(1),
-                       If(self.ack,
-                               seq_start.eq(1),
-                               NextState("WAIT_SEQ")
-                       )
-               )
-               fsm.act("WAIT_SEQ",
-                       self.req.eq(1),
-                       If(seq_done, NextState("IDLE"))
-               )
diff --git a/milkymist/lm32/__init__.py b/milkymist/lm32/__init__.py
deleted file mode 100644 (file)
index 35cf81c..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus import wishbone
-
-class LM32(Module):
-       def __init__(self):
-               self.ibus = i = wishbone.Interface()
-               self.dbus = d = wishbone.Interface()
-               self.interrupt = Signal(32)
-               self.ext_break = Signal()
-
-               ###
-
-               i_adr_o = Signal(32)
-               d_adr_o = Signal(32)
-               self.specials += Instance("lm32_top",
-                       Instance.Input("clk_i", ClockSignal()),
-                       Instance.Input("rst_i", ResetSignal()),
-                       
-                       Instance.Input("interrupt", self.interrupt),
-                       #Instance.Input("ext_break", self.ext_break),
-               
-                       Instance.Output("I_ADR_O", i_adr_o),
-                       Instance.Output("I_DAT_O", i.dat_w),
-                       Instance.Output("I_SEL_O", i.sel),
-                       Instance.Output("I_CYC_O", i.cyc),
-                       Instance.Output("I_STB_O", i.stb),
-                       Instance.Output("I_WE_O", i.we),
-                       Instance.Output("I_CTI_O", i.cti),
-                       Instance.Output("I_LOCK_O"),
-                       Instance.Output("I_BTE_O", i.bte),
-                       Instance.Input("I_DAT_I", i.dat_r),
-                       Instance.Input("I_ACK_I", i.ack),
-                       Instance.Input("I_ERR_I", i.err),
-                       Instance.Input("I_RTY_I", 0),
-                       
-                       Instance.Output("D_ADR_O", d_adr_o),
-                       Instance.Output("D_DAT_O", d.dat_w),
-                       Instance.Output("D_SEL_O", d.sel),
-                       Instance.Output("D_CYC_O", d.cyc),
-                       Instance.Output("D_STB_O", d.stb),
-                       Instance.Output("D_WE_O", d.we),
-                       Instance.Output("D_CTI_O", d.cti),
-                       Instance.Output("D_LOCK_O"),
-                       Instance.Output("D_BTE_O", d.bte),
-                       Instance.Input("D_DAT_I", d.dat_r),
-                       Instance.Input("D_ACK_I", d.ack),
-                       Instance.Input("D_ERR_I", d.err),
-                       Instance.Input("D_RTY_I", 0))
-
-               self.comb += [
-                       self.ibus.adr.eq(i_adr_o[2:]),
-                       self.dbus.adr.eq(d_adr_o[2:])
-               ]
diff --git a/milkymist/memtest/__init__.py b/milkymist/memtest/__init__.py
deleted file mode 100644 (file)
index 9252229..0000000
+++ /dev/null
@@ -1,118 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.misc import optree
-from migen.bank.description import *
-from migen.actorlib import dma_lasmi
-from migen.actorlib.spi import *
-
-@DecorateModule(InsertReset)
-@DecorateModule(InsertCE)
-class LFSR(Module):
-       def __init__(self, n_out, n_state=31, taps=[27, 30]):
-               self.o = Signal(n_out)
-
-               ###
-
-               state = Signal(n_state)
-               curval = [state[i] for i in range(n_state)]
-               curval += [0]*(n_out - n_state)
-               for i in range(n_out):
-                       nv = ~optree("^", [curval[tap] for tap in taps])
-                       curval.insert(0, nv)
-                       curval.pop()
-
-               self.sync += [
-                       state.eq(Cat(*curval[:n_state])),
-                       self.o.eq(Cat(*curval))
-               ]
-
-def _print_lfsr_code():
-       from migen.fhdl import verilog
-       dut = LFSR(3, 4, [3, 2])
-       print(verilog.convert(dut, ios={dut.ce, dut.reset, dut.o}))
-
-class _LFSRTB(Module):
-       def __init__(self, *args, **kwargs):
-               self.submodules.lfsr = LFSR(*args, **kwargs)
-               self.comb += self.lfsr.ce.eq(1)
-
-       def do_simulation(self, s):
-               print("{0:032x}".format(s.rd(self.lfsr.o)))
-
-def _sim_lfsr():
-       from migen.sim.generic import Simulator
-       tb = _LFSRTB(128)
-       sim = Simulator(tb)
-       sim.run(20)
-
-memtest_magic = 0x361f
-
-class MemtestWriter(Module):
-       def __init__(self, lasmim):
-               self._r_magic = CSRStatus(16)
-               self._r_reset = CSR()
-               self._r_shoot = CSR()
-               self.submodules._dma = DMAWriteController(dma_lasmi.Writer(lasmim), MODE_EXTERNAL)
-
-               ###
-
-               self.comb += self._r_magic.status.eq(memtest_magic)
-
-               lfsr = LFSR(lasmim.dw)
-               self.submodules += lfsr
-               self.comb += lfsr.reset.eq(self._r_reset.re)
-
-               en = Signal()
-               en_counter = Signal(lasmim.aw)
-               self.comb += en.eq(en_counter != 0)
-               self.sync += [
-                       If(self._r_shoot.re,
-                               en_counter.eq(self._dma.length)
-                       ).Elif(lfsr.ce,
-                               en_counter.eq(en_counter - 1)
-                       )
-               ]
-
-               self.comb += [
-                       self._dma.trigger.eq(self._r_shoot.re),
-                       self._dma.data.stb.eq(en),
-                       lfsr.ce.eq(en & self._dma.data.ack),
-                       self._dma.data.payload.d.eq(lfsr.o)
-               ]
-
-       def get_csrs(self):
-               return [self._r_magic, self._r_reset, self._r_shoot] + self._dma.get_csrs()
-
-class MemtestReader(Module):
-       def __init__(self, lasmim):
-               self._r_magic = CSRStatus(16)
-               self._r_reset = CSR()
-               self._r_error_count = CSRStatus(lasmim.aw)
-               self.submodules._dma = DMAReadController(dma_lasmi.Reader(lasmim), MODE_SINGLE_SHOT)
-
-               ###
-
-               self.comb += self._r_magic.status.eq(memtest_magic)
-
-               lfsr = LFSR(lasmim.dw)
-               self.submodules += lfsr
-               self.comb += lfsr.reset.eq(self._r_reset.re)
-
-               self.comb += [
-                       lfsr.ce.eq(self._dma.data.stb),
-                       self._dma.data.ack.eq(1)
-               ]
-               err_cnt = self._r_error_count.status
-               self.sync += [
-                       If(self._r_reset.re,
-                               err_cnt.eq(0)
-                       ).Elif(self._dma.data.stb,
-                               If(self._dma.data.payload.d != lfsr.o, err_cnt.eq(err_cnt + 1))
-                       )
-               ]
-
-       def get_csrs(self):
-               return [self._r_magic, self._r_reset, self._r_error_count] + self._dma.get_csrs()
-
-if __name__ == "__main__":
-       _print_lfsr_code()
-       _sim_lfsr()
diff --git a/milkymist/minimac3/__init__.py b/milkymist/minimac3/__init__.py
deleted file mode 100644 (file)
index 37efdd4..0000000
+++ /dev/null
@@ -1,81 +0,0 @@
-from migen.fhdl.std import *
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-from migen.bus import wishbone
-
-_count_width = 11
-
-class MiniMAC(Module, AutoCSR):
-       def __init__(self, pads):
-               # CPU interface
-               self._phy_reset = CSRStorage(reset=1)
-               self._rx_count_0 = CSRStatus(_count_width)
-               self._rx_count_1 = CSRStatus(_count_width)
-               self._tx_count = CSRStorage(_count_width, write_from_dev=True)
-               self._tx_start = CSR()
-               
-               self.submodules.ev = EventManager()
-               self.ev.rx0 = EventSourcePulse()
-               self.ev.rx1 = EventSourcePulse()
-               self.ev.tx = EventSourcePulse()
-               self.ev.finalize()
-               
-               self.membus = wishbone.Interface()
-               
-               ###
-
-               init = Signal(reset=1)
-               self.sync += init.eq(0)
-               rx_ready_0 = Signal()
-               rx_ready_1 = Signal()
-               rx_pending_0 = self.ev.rx0.pending
-               rx_pending_1 = self.ev.rx1.pending
-               rx_pending_0_r = Signal()
-               rx_pending_1_r = Signal()
-               self.comb += [
-                       pads.rst_n.eq(~self._phy_reset.storage),
-                       
-                       rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
-                       rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
-                       
-                       self._tx_count.dat_w.eq(0),
-                       self._tx_count.we.eq(self.ev.tx.trigger)
-               ]
-               self.sync += [
-                       rx_pending_0_r.eq(rx_pending_0),
-                       rx_pending_1_r.eq(rx_pending_1)
-               ]
-               self.specials += Instance("minimac3",
-                               Instance.Input("sys_clk", ClockSignal()),
-                               Instance.Input("sys_rst", ResetSignal()),
-
-                               Instance.Output("rx_done_0", self.ev.rx0.trigger),
-                               Instance.Output("rx_count_0", self._rx_count_0.status),
-                               Instance.Output("rx_done_1", self.ev.rx1.trigger),
-                               Instance.Output("rx_count_1", self._rx_count_1.status),
-                               Instance.Input("rx_ready_0", rx_ready_0),
-                               Instance.Input("rx_ready_1", rx_ready_1),
-
-                               Instance.Input("tx_start", self._tx_start.re),
-                               Instance.Input("tx_count", self._tx_count.storage),
-                               Instance.Output("tx_done", self.ev.tx.trigger),
-                               
-                               Instance.Input("wb_adr_i", self.membus.adr),
-                               Instance.Input("wb_dat_i", self.membus.dat_w),
-                               Instance.Input("wb_sel_i", self.membus.sel),
-                               Instance.Input("wb_stb_i", self.membus.stb),
-                               Instance.Input("wb_cyc_i", self.membus.cyc),
-                               Instance.Input("wb_we_i", self.membus.we),
-                               Instance.Output("wb_dat_o", self.membus.dat_r),
-                               Instance.Output("wb_ack_o", self.membus.ack),
-                               
-                               Instance.Input("phy_tx_clk", ClockSignal("eth_tx")),
-                               Instance.Output("phy_tx_data", pads.tx_data),
-                               Instance.Output("phy_tx_en", pads.tx_en),
-                               Instance.Output("phy_tx_er", pads.tx_er),
-                               Instance.Input("phy_rx_clk", ClockSignal("eth_rx")),
-                               Instance.Input("phy_rx_data", pads.rx_data),
-                               Instance.Input("phy_dv", pads.dv),
-                               Instance.Input("phy_rx_er", pads.rx_er),
-                               Instance.Input("phy_col", pads.col),
-                               Instance.Input("phy_crs", pads.crs))
diff --git a/milkymist/mxcrg/__init__.py b/milkymist/mxcrg/__init__.py
deleted file mode 100644 (file)
index ab11001..0000000
+++ /dev/null
@@ -1,48 +0,0 @@
-from fractions import Fraction
-
-from migen.fhdl.std import *
-
-class MXCRG(Module):
-       def __init__(self, pads, outfreq1x):
-               self.clock_domains.cd_sys = ClockDomain()
-               self.clock_domains.cd_sdram_half = ClockDomain()
-               self.clock_domains.cd_sdram_full_wr = ClockDomain()
-               self.clock_domains.cd_sdram_full_rd = ClockDomain()
-               self.clock_domains.cd_eth_rx = ClockDomain()
-               self.clock_domains.cd_eth_tx = ClockDomain()
-               self.clock_domains.cd_base50 = ClockDomain(reset_less=True)
-
-               self.clk4x_wr_strb = Signal()
-               self.clk4x_rd_strb = Signal()
-
-               ###
-               
-               infreq = 50*1000000
-               ratio = Fraction(outfreq1x)/Fraction(infreq)
-               in_period = float(Fraction(1000000000)/Fraction(infreq))
-
-               self.specials += Instance("mxcrg",
-                       Instance.Parameter("in_period", in_period),
-                       Instance.Parameter("f_mult", ratio.numerator),
-                       Instance.Parameter("f_div", ratio.denominator),
-                       Instance.Input("clk50_pad", pads.clk50),
-                       Instance.Input("trigger_reset", pads.trigger_reset),
-                       
-                       Instance.Input("eth_rx_clk_pad", pads.eth_rx_clk),
-                       Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
-                       
-                       Instance.Output("sys_clk", self.cd_sys.clk),
-                       Instance.Output("sys_rst", self.cd_sys.rst),
-                       Instance.Output("clk2x_270", self.cd_sdram_half.clk),
-                       Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
-                       Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
-                       Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
-                       Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
-                       Instance.Output("base50_clk", self.cd_base50.clk),
-
-                       Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
-                       Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
-                       Instance.Output("norflash_rst_n", pads.norflash_rst_n),
-                       Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
-                       Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
-                       Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk))
diff --git a/milkymist/norflash/__init__.py b/milkymist/norflash/__init__.py
deleted file mode 100644 (file)
index 241d6ac..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from migen.fhdl.std import *
-from migen.bus import wishbone
-from migen.genlib.misc import timeline
-
-class NorFlash(Module):
-       def __init__(self, pads, rd_timing):
-               self.bus = wishbone.Interface()
-       
-               ###
-
-               adr_width = flen(pads.adr) + 1
-               self.comb += [pads.oe_n.eq(0), pads.we_n.eq(1),
-                       pads.ce_n.eq(0)]
-               self.sync += timeline(self.bus.cyc & self.bus.stb, [
-                       (0, [pads.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
-                       (rd_timing, [
-                               self.bus.dat_r[16:].eq(pads.d),
-                               pads.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
-                       (2*rd_timing, [
-                               self.bus.dat_r[:16].eq(pads.d),
-                               self.bus.ack.eq(1)]),
-                       (2*rd_timing + 1, [
-                               self.bus.ack.eq(0)])
-               ])
diff --git a/milkymist/s6ddrphy/__init__.py b/milkymist/s6ddrphy/__init__.py
deleted file mode 100644 (file)
index 119f977..0000000
+++ /dev/null
@@ -1,388 +0,0 @@
-# 1:2 frequency-ratio DDR / LPDDR / DDR2 PHY for 
-# Spartan-6
-# 
-# Assert dfi_wrdata_en and present the data 
-# on dfi_wrdata_mask/dfi_wrdata in the same
-# cycle as the write command.
-#
-# Assert dfi_rddata_en in the same cycle as the read
-# command. The data will come back on dfi_rddata
-# 5 cycles later, along with the assertion 
-# of dfi_rddata_valid.
-#
-# This PHY only supports CAS Latency 3.
-# Read commands must be sent on phase 0.
-# Write commands must be sent on phase 1.
-#
-
-# Todo:
-#      - use CSR for bitslip?
-#      - add configurable CAS Latency
-#      - automatically determines wrphase / rdphase / latencies
-
-from migen.fhdl.std import *
-from migen.bus.dfi import *
-from migen.genlib.record import *
-
-from milkymist import lasmicon
-
-class S6DDRPHY(Module):
-       def __init__(self, pads, memtype, nphases, cl, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
-               if memtype not in ["DDR", "LPDDR", "DDR2"]:
-                       raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
-               if cl != 3:
-                       raise NotImplementedError("S6DDRPHY only supports CAS LATENCY 3")
-               a = flen(pads.a)
-               ba = flen(pads.ba)
-               d = flen(pads.dq)
-
-               self.phy_settings = lasmicon.PhySettings(
-                       memtype=memtype,
-                       dfi_d=2*d,
-                       nphases=nphases,
-                       rdphase=0,
-                       wrphase=1,
-                       rdcmdphase=1,
-                       wrcmdphase=0,
-                       cl=cl,
-                       read_latency=5,
-                       write_latency=0
-               )
-
-               self.dfi = Interface(a, ba, nphases*d, nphases)
-               self.clk4x_wr_strb = Signal()
-               self.clk4x_rd_strb = Signal()
-
-               ###
-
-               # sys_clk           : system clk, used for dfi interface
-               # sdram_half_clk    : half rate sdram clk 
-               # sdram_full_wr_clk : full rate sdram write clk
-               # sdram_full_rd_clk : full rate sdram write clk
-               sd_sys = getattr(self.sync, "sys")
-               sd_sdram_half = getattr(self.sync, "sdram_half")
-
-               sys_clk = ClockSignal("sys")
-               sdram_half_clk = ClockSignal("sdram_half")
-               sdram_full_wr_clk = ClockSignal("sdram_full_wr")
-               sdram_full_rd_clk = ClockSignal("sdram_full_rd")
-
-               # 
-               # Command/address
-               #
-
-               # select active phase
-               #             sys_clk   ----____----____
-               #  phase_sel(nphases=1) 0       0
-               #  phase_sel(nphases=2) 0   1   0   1
-               #  phase_sel(nphases=4) 0 1 2 3 0 1 2 3
-               phase_sel = Signal(log2_int(nphases))
-               sys_clk_d = Signal()
-
-               sd_sdram_half += [
-                       If(sys_clk & ~sys_clk_d, phase_sel.eq(0)
-                       ).Else(phase_sel.eq(phase_sel+1)),
-                       sys_clk_d.eq(sys_clk)
-               ]
-
-               # register dfi cmds on half_rate clk
-               r_dfi = Array(Record(phase_cmd_description(a, ba)) for i in range(nphases))
-               for n, phase in enumerate(self.dfi.phases):
-                       sd_sdram_half +=[
-                               r_dfi[n].address.eq(phase.address),
-                               r_dfi[n].bank.eq(phase.bank),
-                               r_dfi[n].cs_n.eq(phase.cs_n),
-                               r_dfi[n].cke.eq(phase.cke),
-                               r_dfi[n].cas_n.eq(phase.cas_n),
-                               r_dfi[n].ras_n.eq(phase.ras_n),
-                               r_dfi[n].we_n.eq(phase.we_n)
-                       ]
-
-               # output cmds
-               sd_sdram_half += [
-                       pads.a.eq(r_dfi[phase_sel].address),
-                       pads.ba.eq(r_dfi[phase_sel].bank),
-                       pads.cke.eq(r_dfi[phase_sel].cke),
-                       pads.ras_n.eq(r_dfi[phase_sel].ras_n),
-                       pads.cas_n.eq(r_dfi[phase_sel].cas_n),
-                       pads.we_n.eq(r_dfi[phase_sel].we_n)
-               ]
-               if hasattr(pads, "cs_n"):
-                       sd_sdram_half += pads.cs_n.eq(r_dfi[phase_sel].cs_n)
-
-               # 
-               # Bitslip
-               #
-               bitslip_cnt = Signal(4)
-               bitslip_inc = Signal()
-
-               sd_sys += [
-                       If(bitslip_cnt == rd_bitslip,
-                               bitslip_inc.eq(0)
-                       ).Else(
-                               bitslip_cnt.eq(bitslip_cnt+1),
-                               bitslip_inc.eq(1)
-                       )
-               ]
-
-               # 
-               # DQ/DQS/DM data
-               #
-               sdram_half_clk_n = Signal()
-               self.comb += sdram_half_clk_n.eq(~sdram_half_clk)
-
-               postamble = Signal()
-               drive_dqs = Signal()
-               dqs_t_d0 = Signal()
-               dqs_t_d1 = Signal()
-
-               dqs_o = Signal(d//8) 
-               dqs_t = Signal(d//8)
-
-               self.comb += [
-                       dqs_t_d0.eq(~(drive_dqs | postamble)),
-                       dqs_t_d1.eq(~drive_dqs),
-               ]
-
-               for i in range(d//8):
-                       # DQS output
-                       self.specials += Instance("ODDR2",
-                               Instance.Parameter("DDR_ALIGNMENT", dqs_ddr_alignment),
-                               Instance.Parameter("INIT", 0),
-                               Instance.Parameter("SRTYPE", "ASYNC"),
-
-                               Instance.Input("C0", sdram_half_clk),
-                               Instance.Input("C1", sdram_half_clk_n),
-
-                               Instance.Input("CE", 1),
-                               Instance.Input("D0", 0),
-                               Instance.Input("D1", 1),
-                               Instance.Input("R", 0),
-                               Instance.Input("S", 0),
-
-                               Instance.Output("Q", dqs_o[i])
-                       )
-
-                       # DQS tristate cmd
-                       self.specials += Instance("ODDR2",
-                               Instance.Parameter("DDR_ALIGNMENT", dqs_ddr_alignment),
-                               Instance.Parameter("INIT", 0),
-                               Instance.Parameter("SRTYPE", "ASYNC"),
-
-                               Instance.Input("C0", sdram_half_clk),
-                               Instance.Input("C1", sdram_half_clk_n),
-
-                               Instance.Input("CE", 1),
-                               Instance.Input("D0", dqs_t_d0),
-                               Instance.Input("D1", dqs_t_d1),
-                               Instance.Input("R", 0),
-                               Instance.Input("S", 0),
-
-                               Instance.Output("Q", dqs_t[i])
-                       )
-
-                       # DQS tristate buffer
-                       if hasattr(pads, "dqs_n"):
-                               self.specials += Instance("OBUFTDS",
-                                       Instance.Input("I", dqs_o[i]),
-                                       Instance.Input("T", dqs_t[i]),
-
-                                       Instance.Output("O", pads.dqs[i]),
-                                       Instance.Output("OB", pads.dqs_n[i]),
-                               )
-                       else:
-                               self.specials += Instance("OBUFT",
-                                       Instance.Input("I", dqs_o[i]),
-                                       Instance.Input("T", dqs_t[i]),
-
-                                       Instance.Output("O", pads.dqs[i])
-                               )
-
-               sd_sdram_half += postamble.eq(drive_dqs)
-
-               d_dfi = [Record(phase_wrdata_description(nphases*d)+phase_rddata_description(nphases*d)) 
-                       for i in range(2*nphases)]
-
-               for n, phase in enumerate(self.dfi.phases):
-                       self.comb += [
-                               d_dfi[n].wrdata.eq(phase.wrdata),
-                               d_dfi[n].wrdata_mask.eq(phase.wrdata_mask),
-                               d_dfi[n].wrdata_en.eq(phase.wrdata_en),
-                               d_dfi[n].rddata_en.eq(phase.rddata_en),
-                       ]
-                       sd_sys += [
-                               d_dfi[nphases+n].wrdata.eq(phase.wrdata),
-                               d_dfi[nphases+n].wrdata_mask.eq(phase.wrdata_mask)
-                       ]
-
-
-               drive_dq = Signal()
-               drive_dq_n = [Signal() for i in range(2)]
-               self.comb += drive_dq_n[0].eq(~drive_dq)
-               sd_sys += drive_dq_n[1].eq(drive_dq_n[0])
-
-               dq_t = Signal(d)
-               dq_o = Signal(d)
-               dq_i = Signal(d)
-
-               dq_wrdata = []
-               for i in range(2):
-                       for j in reversed(range(nphases)):
-                               dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:d])
-                               dq_wrdata.append(d_dfi[i*nphases+j].wrdata[d:])
-
-               for i in range(d):
-                       # Data serializer
-                       self.specials += Instance("OSERDES2",
-                               Instance.Parameter("DATA_WIDTH", 4),
-                               Instance.Parameter("DATA_RATE_OQ", "SDR"),
-                               Instance.Parameter("DATA_RATE_OT", "SDR"),
-                               Instance.Parameter("SERDES_MODE", "NONE"),
-                               Instance.Parameter("OUTPUT_MODE", "SINGLE_ENDED"),
-
-                               Instance.Output("OQ", dq_o[i]),
-                               Instance.Input("OCE", 1),
-                               Instance.Input("CLK0", sdram_full_wr_clk),
-                               Instance.Input("CLK1", 0),
-                               Instance.Input("IOCE", self.clk4x_wr_strb),
-                               Instance.Input("RST", 0),
-                               Instance.Input("CLKDIV", sys_clk),
-
-                               Instance.Input("D1", dq_wrdata[wr_bitslip+3][i]),
-                               Instance.Input("D2", dq_wrdata[wr_bitslip+2][i]),
-                               Instance.Input("D3", dq_wrdata[wr_bitslip+1][i]),
-                               Instance.Input("D4", dq_wrdata[wr_bitslip+0][i]),
-
-                               Instance.Output("TQ", dq_t[i]),
-                               Instance.Input("T1", drive_dq_n[(wr_bitslip+3)//4]),
-                               Instance.Input("T2", drive_dq_n[(wr_bitslip+2)//4]),
-                               Instance.Input("T3", drive_dq_n[(wr_bitslip+1)//4]),
-                               Instance.Input("T4", drive_dq_n[(wr_bitslip+0)//4]),
-                               Instance.Input("TRAIN", 0),
-                               Instance.Input("TCE", 1),
-                               Instance.Input("SHIFTIN1", 0),
-                               Instance.Input("SHIFTIN2", 0),
-                               Instance.Input("SHIFTIN3", 0),
-                               Instance.Input("SHIFTIN4", 0),
-
-                               Instance.Output("SHIFTOUT1"),
-                               Instance.Output("SHIFTOUT2"),
-                               Instance.Output("SHIFTOUT3"),
-                               Instance.Output("SHIFTOUT4"),
-                       )
-
-                       # Data deserializer
-                       self.specials += Instance("ISERDES2",
-                               Instance.Parameter("DATA_WIDTH", 4),
-                               Instance.Parameter("DATA_RATE", "SDR"),
-                               Instance.Parameter("BITSLIP_ENABLE", "TRUE"),
-                               Instance.Parameter("SERDES_MODE", "NONE"),
-                               Instance.Parameter("INTERFACE_TYPE", "RETIMED"),
-
-                               Instance.Input("D", dq_i[i]),
-                               Instance.Input("CE0", 1),
-                               Instance.Input("CLK0", sdram_full_rd_clk),
-                               Instance.Input("CLK1", 0),
-                               Instance.Input("IOCE", self.clk4x_rd_strb),
-                               Instance.Input("RST", ResetSignal()),
-                               Instance.Input("CLKDIV", sys_clk),
-                               Instance.Output("SHIFTIN"),
-                               Instance.Input("BITSLIP", bitslip_inc),
-                               Instance.Output("FABRICOUT"),
-
-                               Instance.Output("Q1", d_dfi[0*nphases+0].rddata[i+d]),
-                               Instance.Output("Q2", d_dfi[0*nphases+0].rddata[i]),
-                               Instance.Output("Q3", d_dfi[0*nphases+1].rddata[i+d]),
-                               Instance.Output("Q4", d_dfi[0*nphases+1].rddata[i]),
-
-                               Instance.Output("DFB"),
-                               Instance.Output("CFB0"),
-                               Instance.Output("CFB1"),
-                               Instance.Output("VALID"),
-                               Instance.Output("INCDEC"),
-                               Instance.Output("SHIFTOUT")
-                       )
-
-                       # Data buffer
-                       self.specials += Instance("IOBUF",
-                               Instance.Input("I", dq_o[i]),
-                               Instance.Output("O", dq_i[i]),
-                               Instance.Input("T", dq_t[i]),
-                               Instance.InOut("IO", pads.dq[i])
-                       )
-
-               dq_wrdata_mask = []
-               for i in range(2):
-                       for j in reversed(range(nphases)):
-                               dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:d//8])
-                               dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[d//8:])
-
-               for i in range(d//8):
-                       # Mask serializer
-                       self.specials += Instance("OSERDES2",
-                               Instance.Parameter("DATA_WIDTH", 4),
-                               Instance.Parameter("DATA_RATE_OQ", "SDR"),
-                               Instance.Parameter("DATA_RATE_OT", "SDR"),
-                               Instance.Parameter("SERDES_MODE", "NONE"),
-                               Instance.Parameter("OUTPUT_MODE", "SINGLE_ENDED"),
-
-                               Instance.Output("OQ", pads.dm[i]),
-                               Instance.Input("OCE", 1),
-                               Instance.Input("CLK0", sdram_full_wr_clk),
-                               Instance.Input("CLK1", 0),
-                               Instance.Input("IOCE", self.clk4x_wr_strb),
-                               Instance.Input("RST", 0),
-                               Instance.Input("CLKDIV", sys_clk),
-
-                               Instance.Input("D1", dq_wrdata_mask[wr_bitslip+3][i]),
-                               Instance.Input("D2", dq_wrdata_mask[wr_bitslip+2][i]),
-                               Instance.Input("D3", dq_wrdata_mask[wr_bitslip+1][i]),
-                               Instance.Input("D4", dq_wrdata_mask[wr_bitslip+0][i]),
-
-                               Instance.Output("TQ"),
-                               Instance.Input("T1"),
-                               Instance.Input("T2"),
-                               Instance.Input("T3"),
-                               Instance.Input("T4"),
-                               Instance.Input("TRAIN", 0),
-                               Instance.Input("TCE", 0),
-                               Instance.Input("SHIFTIN1", 0),
-                               Instance.Input("SHIFTIN2", 0),
-                               Instance.Input("SHIFTIN3", 0),
-                               Instance.Input("SHIFTIN4", 0),
-
-                               Instance.Output("SHIFTOUT1"),
-                               Instance.Output("SHIFTOUT2"),
-                               Instance.Output("SHIFTOUT3"),
-                               Instance.Output("SHIFTOUT4"),
-                       )
-
-               #
-               # ODT
-               #
-               # ODT not yet supported
-               if hasattr(pads, "odt"):
-                       self.comb += pads.odt.eq(0)
-
-               # 
-               # DQ/DQS/DM control
-               #
-               self.comb += drive_dq.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
-
-               d_dfi_wrdata_en = Signal()
-               sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
-               
-               r_dfi_wrdata_en = Signal(2)
-               sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en[0])) 
-
-               self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
-
-               rddata_sr = Signal(self.phy_settings.read_latency)
-               sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.phy_settings.read_latency],
-                       d_dfi[self.phy_settings.rdphase].rddata_en))
-               
-               for n, phase in enumerate(self.dfi.phases):
-                       self.comb += [
-                               phase.rddata.eq(d_dfi[n].rddata),
-                               phase.rddata_valid.eq(rddata_sr[0]),
-                       ]
diff --git a/milkymist/s6ddrphy/initsequence.py b/milkymist/s6ddrphy/initsequence.py
deleted file mode 100644 (file)
index 3c4c65b..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-from migen.fhdl.std import log2_int
-
-def get_sdram_phy_header(sdram_phy):
-       if sdram_phy.phy_settings.memtype not in ["SDR", "DDR", "LPDDR", "DDR2"]:
-               raise NotImplementedError("The SDRAM PHY header generator only supports SDR, DDR, LPDDR and DDR2")
-
-       r = "#ifndef __HW_SDRAM_PHY_H\n#define __HW_SDRAM_PHY_H\n"
-       r += "#include <hw/common.h>\n#include <hw/csr.h>\n#include <hw/flags.h>\n\n"
-
-       r += "static void cdelay(int i);\n"
-
-       #
-       # commands_px functions
-       # 
-       for n in range(sdram_phy.phy_settings.nphases):
-               r += """
-static void command_p{n}(int cmd)
-{{
-       dfii_pi{n}_command_write(cmd);
-       dfii_pi{n}_command_issue_write(1);
-}}""".format(n=str(n))
-       r += "\n\n"
-
-       #
-       # rd/wr access macros
-       #
-       r += """
-#define dfii_pird_address_write(X) dfii_pi{rdphase}_address_write(X)
-#define dfii_piwr_address_write(X) dfii_pi{wrphase}_address_write(X)
-
-#define dfii_pird_baddress_write(X) dfii_pi{rdphase}_baddress_write(X)
-#define dfii_piwr_baddress_write(X) dfii_pi{wrphase}_baddress_write(X)
-
-#define command_prd(X) command_p{rdphase}(X)
-#define command_pwr(X) command_p{wrphase}(X)
-""".format(rdphase=str(sdram_phy.phy_settings.rdphase), wrphase=str(sdram_phy.phy_settings.wrphase)) 
-       r +="\n"
-       
-       #
-       # init sequence
-       # 
-       cmds = {
-               "PRECHARGE_ALL" : "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
-               "MODE_REGISTER" : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
-               "AUTO_REFRESH"  : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
-               "CKE"           : "DFII_CONTROL_CKE"
-       }
-
-       def gen_cmd(comment, a, ba, cmd, delay):        
-               r = "\t/* {0} */\n".format(comment)
-               r += "\tdfii_pi0_address_write({0:#x});\n".format(a)
-               r += "\tdfii_pi0_baddress_write({0:d});\n".format(ba)
-               if "CKE" in cmd:
-                       r += "\tdfii_control_write({0});\n".format(cmd)
-               else:
-                       r += "\tcommand_p0({0});\n".format(cmd)
-               r += "\tcdelay({0:d});\n".format(delay)
-               r += "\n"
-               return r
-
-
-       r += "static void init_sequence(void)\n{\n"
-
-       cl = sdram_phy.phy_settings.cl
-       
-       if sdram_phy.phy_settings.memtype == "SDR":
-               bl = 1*sdram_phy.phy_settings.nphases
-               mr  = log2_int(bl) + (cl << 4)
-               reset_dll = 1 << 8
-
-               init_sequence = [
-                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
-                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
-                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
-               ]
-
-       elif sdram_phy.phy_settings.memtype == "DDR":
-               bl = 2*sdram_phy.phy_settings.nphases
-               mr  = log2_int(bl) + (cl << 4)
-               emr = 0
-               reset_dll = 1 << 8
-
-               init_sequence = [
-                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
-                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
-                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
-                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
-               ]
-
-       elif sdram_phy.phy_settings.memtype == "LPDDR":
-               bl = 2*sdram_phy.phy_settings.nphases
-               mr  = log2_int(bl) + (cl << 4)
-               emr = 0
-               reset_dll = 1 << 8
-
-               init_sequence = [
-                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
-                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
-                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
-                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
-               ]
-
-       elif sdram_phy.phy_settings.memtype == "DDR2":
-               bl = 2*sdram_phy.phy_settings.nphases
-               wr = 2
-               mr  = log2_int(bl) + (cl << 4) + (wr << 9)
-               emr = 0
-               emr2 = 0
-               emr3 = 0
-               reset_dll = 1 << 8
-               ocd = 7 << 7
-
-               init_sequence = [
-                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
-                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
-                       ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
-                       ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
-                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
-                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
-                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
-                       ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
-                       ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
-               ]
-
-       for comment, a, ba, cmd, delay in init_sequence:
-               r += gen_cmd(comment, a, ba, cmd, delay)
-
-       r += "}\n"
-       r += "#endif\n"
-
-       return r
diff --git a/milkymist/timer/__init__.py b/milkymist/timer/__init__.py
deleted file mode 100644 (file)
index 3d1ab70..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from migen.fhdl.std import *
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-
-class Timer(Module, AutoCSR):
-       def __init__(self, width=32):
-               self._load = CSRStorage(width)
-               self._reload = CSRStorage(width)
-               self._en = CSRStorage()
-               self._update_value = CSR()
-               self._value = CSRStatus(width)
-               
-               self.submodules.ev = EventManager()
-               self.ev.zero = EventSourceProcess()
-               self.ev.finalize()
-
-               ###
-
-               value = Signal(width)
-               self.sync += [
-                       If(self._en.storage,
-                               If(value == 0,
-                                       # set reload to 0 to disable reloading
-                                       value.eq(self._reload.storage)
-                               ).Else(
-                                       value.eq(value - 1)
-                               )
-                       ).Else(
-                               value.eq(self._load.storage)
-                       ),
-                       If(self._update_value.re, self._value.status.eq(value))
-               ]
-               self.comb += self.ev.zero.trigger.eq(value != 0)
diff --git a/milkymist/uart/__init__.py b/milkymist/uart/__init__.py
deleted file mode 100644 (file)
index 25530d6..0000000
+++ /dev/null
@@ -1,99 +0,0 @@
-from migen.fhdl.std import *
-from migen.genlib.cdc import MultiReg
-from migen.bank.description import *
-from migen.bank.eventmanager import *
-
-class UART(Module, AutoCSR):
-       def __init__(self, pads, clk_freq, baud=115200):
-               self._rxtx = CSR(8)
-               self._divisor = CSRStorage(16, reset=int(clk_freq/baud/16))
-               
-               self.submodules.ev = EventManager()
-               self.ev.tx = EventSourceProcess()
-               self.ev.rx = EventSourcePulse()
-               self.ev.finalize()
-       
-               ###
-
-               pads.tx.reset = 1
-
-               enable16 = Signal()
-               enable16_counter = Signal(16)
-               self.comb += enable16.eq(enable16_counter == 0)
-               self.sync += [
-                       enable16_counter.eq(enable16_counter - 1),
-                       If(enable16,
-                               enable16_counter.eq(self._divisor.storage - 1))
-               ]
-               
-               # TX
-               tx_reg = Signal(8)
-               tx_bitcount = Signal(4)
-               tx_count16 = Signal(4)
-               tx_busy = self.ev.tx.trigger
-               self.sync += [
-                       If(self._rxtx.re,
-                               tx_reg.eq(self._rxtx.r),
-                               tx_bitcount.eq(0),
-                               tx_count16.eq(1),
-                               tx_busy.eq(1),
-                               pads.tx.eq(0)
-                       ).Elif(enable16 & tx_busy,
-                               tx_count16.eq(tx_count16 + 1),
-                               If(tx_count16 == 0,
-                                       tx_bitcount.eq(tx_bitcount + 1),
-                                       If(tx_bitcount == 8,
-                                               pads.tx.eq(1)
-                                       ).Elif(tx_bitcount == 9,
-                                               pads.tx.eq(1),
-                                               tx_busy.eq(0)
-                                       ).Else(
-                                               pads.tx.eq(tx_reg[0]),
-                                               tx_reg.eq(Cat(tx_reg[1:], 0))
-                                       )
-                               )
-                       )
-               ]
-               
-               # RX
-               rx = Signal()
-               self.specials += MultiReg(pads.rx, rx)
-               rx_r = Signal()
-               rx_reg = Signal(8)
-               rx_bitcount = Signal(4)
-               rx_count16 = Signal(4)
-               rx_busy = Signal()
-               rx_done = self.ev.rx.trigger
-               rx_data = self._rxtx.w
-               self.sync += [
-                       rx_done.eq(0),
-                       If(enable16,
-                               rx_r.eq(rx),
-                               If(~rx_busy,
-                                       If(~rx & rx_r, # look for start bit
-                                               rx_busy.eq(1),
-                                               rx_count16.eq(7),
-                                               rx_bitcount.eq(0)
-                                       )
-                               ).Else(
-                                       rx_count16.eq(rx_count16 + 1),
-                                       If(rx_count16 == 0,
-                                               rx_bitcount.eq(rx_bitcount + 1),
-
-                                               If(rx_bitcount == 0,
-                                                       If(rx, # verify start bit
-                                                               rx_busy.eq(0)
-                                                       )
-                                               ).Elif(rx_bitcount == 9,
-                                                       rx_busy.eq(0),
-                                                       If(rx, # verify stop bit
-                                                               rx_data.eq(rx_reg),
-                                                               rx_done.eq(1)
-                                                       )
-                                               ).Else(
-                                                       rx_reg.eq(Cat(rx_reg[1:], rx))
-                                               )
-                                       )
-                               )
-                       )
-               ]
diff --git a/misoclib/__init__.py b/misoclib/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/misoclib/counteradc/__init__.py b/misoclib/counteradc/__init__.py
new file mode 100644 (file)
index 0000000..9df83c3
--- /dev/null
@@ -0,0 +1,61 @@
+import collections
+
+from migen.fhdl.std import *
+from migen.bank.description import *
+from migen.genlib.misc import optree
+from migen.genlib.cdc import MultiReg
+
+class CounterADC(Module, AutoCSR):
+       def __init__(self, charge, sense, width=24):
+               if not isinstance(sense, collections.Iterable):
+                       sense = [sense]
+
+               channels = len(sense)
+
+               self._start_busy = CSR()
+               self._overflow = CSRStatus(channels)
+               self._polarity = CSRStorage()
+
+               count = Signal(width)
+               busy = Signal(channels)
+
+               res = []
+               for i in range(channels):
+                       res.append(CSRStatus(width, name="res"+str(i)))
+                       setattr(self, "_res"+str(i), res[-1])
+
+               any_busy = Signal()
+               self.comb += [
+                       any_busy.eq(optree("|",
+                           [busy[i] for i in range(channels)])),
+                       self._start_busy.w.eq(any_busy)
+               ]
+
+               carry = Signal()
+
+               self.sync += [
+                       If(self._start_busy.re,
+                               count.eq(0),
+                               busy.eq((1 << channels)-1),
+                               self._overflow.status.eq(0),
+                               charge.eq(~self._polarity.storage)
+                       ).Elif(any_busy,
+                               Cat(count, carry).eq(count + 1),
+                               If(carry,
+                                       self._overflow.status.eq(busy),
+                                       busy.eq(0)
+                               )
+                       ).Else(
+                               charge.eq(self._polarity.storage)
+                       )
+               ]
+
+               for i in range(channels):
+                       sense_synced = Signal()
+                       self.specials += MultiReg(sense[i], sense_synced)
+                       self.sync += If(busy[i],
+                               If(sense_synced != self._polarity.storage,
+                                       res[i].status.eq(count),
+                                       busy[i].eq(0)
+                               )
+                       )
diff --git a/misoclib/cpuif.py b/misoclib/cpuif.py
new file mode 100644 (file)
index 0000000..b246774
--- /dev/null
@@ -0,0 +1,64 @@
+from migen.bank.description import CSRStatus
+
+def _get_rw_functions(reg_name, reg_base, size, read_only):
+       r = ""
+       if size > 8:
+               raise NotImplementedError("Register too large")
+       elif size > 4:
+               ctype = "unsigned long long int"
+       elif size > 2:
+               ctype = "unsigned int"
+       elif size > 1:
+               ctype = "unsigned short int"
+       else:
+               ctype = "unsigned char"
+
+       r += "static inline "+ctype+" "+reg_name+"_read(void) {\n"
+       if size > 1:
+               r += "\t"+ctype+" r = MMPTR("+hex(reg_base)+");\n"
+               for byte in range(1, size):
+                       r += "\tr <<= 8;\n\tr |= MMPTR("+hex(reg_base+4*byte)+");\n"
+               r += "\treturn r;\n}\n"
+       else:
+               r += "\treturn MMPTR("+hex(reg_base)+");\n}\n"
+
+       if not read_only:
+               r += "static inline void "+reg_name+"_write("+ctype+" value) {\n"
+               for byte in range(size):
+                       shift = (size-byte-1)*8
+                       if shift:
+                               value_shifted = "value >> "+str(shift)
+                       else:
+                               value_shifted = "value"
+                       r += "\tMMPTR("+hex(reg_base+4*byte)+") = "+value_shifted+";\n"
+               r += "}\n"
+       return r
+
+def get_csr_header(csr_base, bank_array, interrupt_map):
+       r = "#ifndef __HW_CSR_H\n#define __HW_CSR_H\n#include <hw/common.h>\n"
+       for name, csrs, mapaddr, rmap in bank_array.banks:
+               r += "\n/* "+name+" */\n"
+               reg_base = csr_base + 0x800*mapaddr
+               r += "#define "+name.upper()+"_BASE "+hex(reg_base)+"\n"
+               for csr in csrs:
+                       nr = (csr.size + 7)//8
+                       r += _get_rw_functions(name + "_" + csr.name, reg_base, nr, isinstance(csr, CSRStatus))
+                       reg_base += 4*nr
+               try:
+                       interrupt_nr = interrupt_map[name]
+               except KeyError:
+                       pass
+               else:
+                       r += "#define "+name.upper()+"_INTERRUPT "+str(interrupt_nr)+"\n"
+       r += "\n#endif\n"
+       return r
+
+def get_csr_csv(csr_base, bank_array):
+       r = ""
+       for name, csrs, mapaddr, rmap in bank_array.banks:
+               reg_base = csr_base + 0x800*mapaddr
+               for csr in csrs:
+                       nr = (csr.size + 7)//8
+                       r += "{}_{},0x{:08x},{},{}\n".format(name, csr.name, reg_base, nr, "ro" if isinstance(csr, CSRStatus) else "rw")
+                       reg_base += 4*nr
+       return r
diff --git a/misoclib/dfii/__init__.py b/misoclib/dfii/__init__.py
new file mode 100644 (file)
index 0000000..22a5bcd
--- /dev/null
@@ -0,0 +1,55 @@
+from migen.fhdl.std import *
+from migen.bus import dfi
+from migen.bank.description import *
+
+class PhaseInjector(Module, AutoCSR):
+       def __init__(self, phase):
+               self._command = CSRStorage(6) # cs, we, cas, ras, wren, rden
+               self._command_issue = CSR()
+               self._address = CSRStorage(flen(phase.address))
+               self._baddress = CSRStorage(flen(phase.bank))
+               self._wrdata = CSRStorage(flen(phase.wrdata))
+               self._rddata = CSRStatus(flen(phase.rddata))
+       
+               ###
+
+               self.comb += [
+                       If(self._command_issue.re,
+                               phase.cs_n.eq(~self._command.storage[0]),
+                               phase.we_n.eq(~self._command.storage[1]),
+                               phase.cas_n.eq(~self._command.storage[2]),
+                               phase.ras_n.eq(~self._command.storage[3])
+                       ).Else(
+                               phase.cs_n.eq(1),
+                               phase.we_n.eq(1),
+                               phase.cas_n.eq(1),
+                               phase.ras_n.eq(1)
+                       ),
+                       phase.address.eq(self._address.storage),
+                       phase.bank.eq(self._baddress.storage),
+                       phase.wrdata_en.eq(self._command_issue.re & self._command.storage[4]),
+                       phase.rddata_en.eq(self._command_issue.re & self._command.storage[5]),
+                       phase.wrdata.eq(self._wrdata.storage),
+                       phase.wrdata_mask.eq(0)
+               ]
+               self.sync += If(phase.rddata_valid, self._rddata.status.eq(phase.rddata))
+
+class DFIInjector(Module, AutoCSR):
+       def __init__(self, a, ba, d, nphases=1):
+               inti = dfi.Interface(a, ba, d, nphases)
+               self.slave = dfi.Interface(a, ba, d, nphases)
+               self.master = dfi.Interface(a, ba, d, nphases)
+               
+               self._control = CSRStorage(2) # sel, cke
+               
+               for n, phase in enumerate(inti.phases):
+                       setattr(self.submodules, "pi" + str(n), PhaseInjector(phase))
+       
+               ###
+       
+               self.comb += If(self._control.storage[0],
+                               self.slave.connect(self.master)
+                       ).Else(
+                               inti.connect(self.master)
+                       )
+               self.comb += [phase.cke.eq(self._control.storage[1]) for phase in inti.phases]
diff --git a/misoclib/dvisampler/__init__.py b/misoclib/dvisampler/__init__.py
new file mode 100644 (file)
index 0000000..fb1bbb8
--- /dev/null
@@ -0,0 +1,79 @@
+from migen.fhdl.std import *
+from migen.bank.description import AutoCSR
+
+from misoclib.dvisampler.edid import EDID
+from misoclib.dvisampler.clocking import Clocking
+from misoclib.dvisampler.datacapture import DataCapture
+from misoclib.dvisampler.charsync import CharSync
+from misoclib.dvisampler.wer import WER
+from misoclib.dvisampler.decoding import Decoding
+from misoclib.dvisampler.chansync import ChanSync
+from misoclib.dvisampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction
+from misoclib.dvisampler.dma import DMA
+
+class DVISampler(Module, AutoCSR):
+       def __init__(self, pads, asmiport, n_dma_slots=2):
+               self.submodules.edid = EDID(pads)
+               self.submodules.clocking = Clocking(pads)
+
+               for datan in range(3):
+                       name = "data" + str(datan)
+                       
+                       cap = DataCapture(getattr(pads, name + "_p"), getattr(pads, name + "_n"), 8)
+                       setattr(self.submodules, name + "_cap", cap)
+                       self.comb += cap.serdesstrobe.eq(self.clocking.serdesstrobe)
+
+                       charsync = CharSync()
+                       setattr(self.submodules, name + "_charsync", charsync)
+                       self.comb += charsync.raw_data.eq(cap.d)
+
+                       wer = WER()
+                       setattr(self.submodules, name + "_wer", wer)
+                       self.comb += wer.data.eq(charsync.data)
+
+                       decoding = Decoding()
+                       setattr(self.submodules, name + "_decod", decoding)
+                       self.comb += [
+                               decoding.valid_i.eq(charsync.synced),
+                               decoding.input.eq(charsync.data)
+                       ]
+
+               self.submodules.chansync = ChanSync()
+               self.comb += [
+                       self.chansync.valid_i.eq(self.data0_decod.valid_o & \
+                         self.data1_decod.valid_o & self.data2_decod.valid_o),
+                       self.chansync.data_in0.eq(self.data0_decod.output),
+                       self.chansync.data_in1.eq(self.data1_decod.output),
+                       self.chansync.data_in2.eq(self.data2_decod.output),
+               ]
+
+               self.submodules.syncpol = SyncPolarity()
+               self.comb += [
+                       self.syncpol.valid_i.eq(self.chansync.chan_synced),
+                       self.syncpol.data_in0.eq(self.chansync.data_out0),
+                       self.syncpol.data_in1.eq(self.chansync.data_out1),
+                       self.syncpol.data_in2.eq(self.chansync.data_out2)
+               ]
+
+               self.submodules.resdetection = ResolutionDetection()
+               self.comb += [
+                       self.resdetection.valid_i.eq(self.syncpol.valid_o),
+                       self.resdetection.de.eq(self.syncpol.de),
+                       self.resdetection.vsync.eq(self.syncpol.vsync)
+               ]
+
+               self.submodules.frame = FrameExtraction()
+               self.comb += [
+                       self.frame.valid_i.eq(self.syncpol.valid_o),
+                       self.frame.de.eq(self.syncpol.de),
+                       self.frame.vsync.eq(self.syncpol.vsync),
+                       self.frame.r.eq(self.syncpol.r),
+                       self.frame.g.eq(self.syncpol.g),
+                       self.frame.b.eq(self.syncpol.b)
+               ]
+
+               self.submodules.dma = DMA(asmiport, n_dma_slots)
+               self.comb += self.frame.frame.connect(self.dma.frame)
+               self.ev = self.dma.ev
+
+       autocsr_exclude = {"ev"}
diff --git a/misoclib/dvisampler/analysis.py b/misoclib/dvisampler/analysis.py
new file mode 100644 (file)
index 0000000..17579f7
--- /dev/null
@@ -0,0 +1,183 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg, PulseSynchronizer
+from migen.genlib.fifo import AsyncFIFO
+from migen.genlib.record import Record
+from migen.bank.description import *
+from migen.flow.actor import *
+
+from misoclib.dvisampler.common import channel_layout, frame_layout
+
+class SyncPolarity(Module):
+       def __init__(self):
+               self.valid_i = Signal()
+               self.data_in0 = Record(channel_layout)
+               self.data_in1 = Record(channel_layout)
+               self.data_in2 = Record(channel_layout)
+
+               self.valid_o = Signal()
+               self.de = Signal()
+               self.hsync = Signal()
+               self.vsync = Signal()
+               self.r = Signal(8)
+               self.g = Signal(8)
+               self.b = Signal(8)
+
+               ###
+
+               de = self.data_in0.de
+               de_r = Signal()
+               c = self.data_in0.c
+               c_polarity = Signal(2)
+               c_out = Signal(2)
+
+               self.comb += [
+                       self.de.eq(de_r),
+                       self.hsync.eq(c_out[0]),
+                       self.vsync.eq(c_out[1])
+               ]
+
+               self.sync.pix += [
+                       self.valid_o.eq(self.valid_i),
+                       self.r.eq(self.data_in2.d),
+                       self.g.eq(self.data_in1.d),
+                       self.b.eq(self.data_in0.d),
+
+                       de_r.eq(de),
+                       If(de_r & ~de,
+                               c_polarity.eq(c),
+                               c_out.eq(0)
+                       ).Else(
+                               c_out.eq(c ^ c_polarity)
+                       )
+               ]
+
+class ResolutionDetection(Module, AutoCSR):
+       def __init__(self, nbits=11):
+               self.valid_i = Signal()
+               self.vsync = Signal()
+               self.de = Signal()
+
+               self._hres = CSRStatus(nbits)
+               self._vres = CSRStatus(nbits)
+
+               ###
+
+               # Detect DE transitions
+               de_r = Signal()
+               pn_de = Signal()
+               self.sync.pix += de_r.eq(self.de)
+               self.comb += pn_de.eq(~self.de & de_r)
+
+               # HRES
+               hcounter = Signal(nbits)
+               self.sync.pix += If(self.valid_i & self.de,
+                               hcounter.eq(hcounter + 1)
+                       ).Else(
+                               hcounter.eq(0)
+                       )
+
+               hcounter_st = Signal(nbits)
+               self.sync.pix += If(self.valid_i,
+                               If(pn_de, hcounter_st.eq(hcounter))
+                       ).Else(
+                               hcounter_st.eq(0)
+                       )
+               self.specials += MultiReg(hcounter_st, self._hres.status)
+
+               # VRES
+               vsync_r = Signal()
+               p_vsync = Signal()
+               self.sync.pix += vsync_r.eq(self.vsync),
+               self.comb += p_vsync.eq(self.vsync & ~vsync_r)
+
+               vcounter = Signal(nbits)
+               self.sync.pix += If(self.valid_i & p_vsync,
+                               vcounter.eq(0)
+                       ).Elif(pn_de,
+                               vcounter.eq(vcounter + 1)
+                       )
+
+               vcounter_st = Signal(nbits)
+               self.sync.pix += If(self.valid_i,
+                               If(p_vsync, vcounter_st.eq(vcounter))
+                       ).Else(
+                               vcounter_st.eq(0)
+                       )
+               self.specials += MultiReg(vcounter_st, self._vres.status)
+
+class FrameExtraction(Module, AutoCSR):
+       def __init__(self):
+               # in pix clock domain
+               self.valid_i = Signal()
+               self.vsync = Signal()
+               self.de = Signal()
+               self.r = Signal(8)
+               self.g = Signal(8)
+               self.b = Signal(8)
+
+               # in sys clock domain
+               self.frame = Source(frame_layout)
+               self.busy = Signal()
+
+               self._r_overflow = CSR()
+
+               ###
+
+               fifo_stb = Signal()
+               fifo_in = Record(frame_layout)
+               self.comb += [
+                       fifo_stb.eq(self.valid_i & self.de),
+                       fifo_in.r.eq(self.r),
+                       fifo_in.g.eq(self.g),
+                       fifo_in.b.eq(self.b),
+               ]
+               vsync_r = Signal()
+               self.sync.pix += [
+                       If(self.vsync & ~vsync_r, fifo_in.parity.eq(~fifo_in.parity)),
+                       vsync_r.eq(self.vsync)
+               ]
+
+               fifo = RenameClockDomains(AsyncFIFO(layout_len(frame_layout), 512),
+                       {"write": "pix", "read": "sys"})
+               self.submodules += fifo
+               self.comb += [
+                       fifo.we.eq(fifo_stb),
+                       fifo.din.eq(fifo_in.raw_bits()),
+                       self.frame.stb.eq(fifo.readable),
+                       self.frame.payload.raw_bits().eq(fifo.dout),
+                       fifo.re.eq(self.frame.ack),
+                       self.busy.eq(0)
+               ]
+
+               # overflow detection
+               pix_overflow = Signal()
+               pix_overflow_reset = Signal()
+               self.sync.pix += [
+                       If(fifo.we & ~fifo.writable,
+                               pix_overflow.eq(1)
+                       ).Elif(pix_overflow_reset,
+                               pix_overflow.eq(0)
+                       )
+               ]
+
+               sys_overflow = Signal()
+               self.specials += MultiReg(pix_overflow, sys_overflow)
+               self.submodules.overflow_reset = PulseSynchronizer("sys", "pix")
+               self.submodules.overflow_reset_ack = PulseSynchronizer("pix", "sys")
+               self.comb += [
+                       pix_overflow_reset.eq(self.overflow_reset.o),
+                       self.overflow_reset_ack.i.eq(pix_overflow_reset)
+               ]
+
+               overflow_mask = Signal()
+               self.comb += [
+                       self._r_overflow.w.eq(sys_overflow & ~overflow_mask),
+                       self.overflow_reset.i.eq(self._r_overflow.re)
+               ]
+               self.sync += [
+                       If(self._r_overflow.re,
+                               overflow_mask.eq(1)
+                       ).Elif(self.overflow_reset_ack.o,
+                               overflow_mask.eq(0)
+                       )
+               ]
diff --git a/misoclib/dvisampler/chansync.py b/misoclib/dvisampler/chansync.py
new file mode 100644 (file)
index 0000000..270ef40
--- /dev/null
@@ -0,0 +1,88 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.genlib.fifo import _inc
+from migen.genlib.record import Record, layout_len
+from migen.genlib.misc import optree
+from migen.bank.description import *
+
+from misoclib.dvisampler.common import channel_layout
+
+class _SyncBuffer(Module):
+       def __init__(self, width, depth):
+               self.din = Signal(width)
+               self.dout = Signal(width)
+               self.re = Signal()
+
+               ###
+
+               produce = Signal(max=depth)
+               consume = Signal(max=depth)
+               storage = Memory(width, depth)
+               self.specials += storage
+
+               wrport = storage.get_port(write_capable=True)
+               self.specials += wrport
+               self.comb += [
+                       wrport.adr.eq(produce),
+                       wrport.dat_w.eq(self.din),
+                       wrport.we.eq(1)
+               ]
+               self.sync += _inc(produce, depth)
+
+               rdport = storage.get_port(async_read=True)
+               self.specials += rdport
+               self.comb += [
+                       rdport.adr.eq(consume),
+                       self.dout.eq(rdport.dat_r)
+               ]
+               self.sync += If(self.re, _inc(consume, depth))
+
+class ChanSync(Module, AutoCSR):
+       def __init__(self, nchan=3, depth=8):
+               self.valid_i = Signal()
+               self.chan_synced = Signal()
+
+               self._r_channels_synced = CSRStatus()
+
+               lst_control = []
+               all_control = Signal()
+               for i in range(nchan):
+                       name = "data_in" + str(i)
+                       data_in = Record(channel_layout, name=name)
+                       setattr(self, name, data_in)
+                       name = "data_out" + str(i)
+                       data_out = Record(channel_layout, name=name)
+                       setattr(self, name, data_out)
+
+                       ###
+               
+                       syncbuffer = RenameClockDomains(_SyncBuffer(layout_len(channel_layout), depth), "pix")
+                       self.submodules += syncbuffer
+                       self.comb += [
+                               syncbuffer.din.eq(data_in.raw_bits()),
+                               data_out.raw_bits().eq(syncbuffer.dout)
+                       ]
+                       is_control = Signal()
+                       self.comb += [
+                               is_control.eq(~data_out.de),
+                               syncbuffer.re.eq(~is_control | all_control)
+                       ]
+                       lst_control.append(is_control)
+
+               some_control = Signal()
+               self.comb += [
+                       all_control.eq(optree("&", lst_control)),
+                       some_control.eq(optree("|", lst_control))
+               ]
+               self.sync.pix += If(~self.valid_i,
+                               self.chan_synced.eq(0)
+                       ).Else(
+                               If(some_control,
+                                       If(all_control,
+                                               self.chan_synced.eq(1)
+                                       ).Else(
+                                               self.chan_synced.eq(0)
+                                       )
+                               )
+                       )
+               self.specials += MultiReg(self.chan_synced, self._r_channels_synced.status)
diff --git a/misoclib/dvisampler/charsync.py b/misoclib/dvisampler/charsync.py
new file mode 100644 (file)
index 0000000..99ea9aa
--- /dev/null
@@ -0,0 +1,53 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.genlib.misc import optree
+from migen.bank.description import *
+
+from misoclib.dvisampler.common import control_tokens
+
+class CharSync(Module, AutoCSR):
+       def __init__(self, required_controls=8):
+               self.raw_data = Signal(10)
+               self.synced = Signal()
+               self.data = Signal(10)
+
+               self._r_char_synced = CSRStatus()
+               self._r_ctl_pos = CSRStatus(bits_for(9))
+
+               ###
+
+               raw_data1 = Signal(10)
+               self.sync.pix += raw_data1.eq(self.raw_data)
+               raw = Signal(20)
+               self.comb += raw.eq(Cat(raw_data1, self.raw_data))
+
+               found_control = Signal()
+               control_position = Signal(max=10)
+               self.sync.pix += found_control.eq(0)
+               for i in range(10):
+                       self.sync.pix += If(optree("|", [raw[i:i+10] == t for t in control_tokens]),
+                               found_control.eq(1),
+                               control_position.eq(i)
+                       )
+
+               control_counter = Signal(max=required_controls)
+               previous_control_position = Signal(max=10)
+               word_sel = Signal(max=10)
+               self.sync.pix += [
+                       If(found_control & (control_position == previous_control_position),
+                               If(control_counter == (required_controls - 1),
+                                       control_counter.eq(0),
+                                       self.synced.eq(1),
+                                       word_sel.eq(control_position)
+                               ).Else(
+                                       control_counter.eq(control_counter + 1)
+                               )
+                       ).Else(
+                               control_counter.eq(0)
+                       ),
+                       previous_control_position.eq(control_position)
+               ]
+               self.specials += MultiReg(self.synced, self._r_char_synced.status)
+               self.specials += MultiReg(word_sel, self._r_ctl_pos.status)
+
+               self.sync.pix += self.data.eq(raw >> word_sel)
diff --git a/misoclib/dvisampler/clocking.py b/misoclib/dvisampler/clocking.py
new file mode 100644 (file)
index 0000000..bcfca52
--- /dev/null
@@ -0,0 +1,57 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+
+class Clocking(Module, AutoCSR):
+       def __init__(self, pads):
+               self._r_pll_reset = CSRStorage(reset=1)
+               self._r_locked = CSRStatus()
+
+               self.locked = Signal()
+               self.serdesstrobe = Signal()
+               self.clock_domains._cd_pix = ClockDomain()
+               self.clock_domains._cd_pix2x = ClockDomain()
+               self.clock_domains._cd_pix10x = ClockDomain(reset_less=True)
+
+               ###
+
+               clk_se = Signal()
+               self.specials += Instance("IBUFDS", i_I=pads.clk_p, i_IB=pads.clk_n, o_O=clk_se)
+
+               clkfbout = Signal()
+               pll_locked = Signal()
+               pll_clk0 = Signal()
+               pll_clk1 = Signal()
+               pll_clk2 = Signal()
+               self.specials += Instance("PLL_BASE",
+                       p_CLKIN_PERIOD=26.7,
+                       p_CLKFBOUT_MULT=20,
+                       p_CLKOUT0_DIVIDE=2,  # pix10x
+                       p_CLKOUT1_DIVIDE=10, # pix2x
+                       p_CLKOUT2_DIVIDE=20, # pix
+                       p_COMPENSATION="INTERNAL",
+                       
+                       i_CLKIN=clk_se,
+                       o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
+                       o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
+                       o_LOCKED=pll_locked, i_RST=self._r_pll_reset.storage)
+
+               locked_async = Signal()
+               self.specials += [
+                       Instance("BUFPLL", p_DIVIDE=5,
+                               i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
+                               o_IOCLK=self._cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
+                       Instance("BUFG", i_I=pll_clk1, o_O=self._cd_pix2x.clk),
+                       Instance("BUFG", i_I=pll_clk2, o_O=self._cd_pix.clk),
+                       MultiReg(locked_async, self.locked, "sys")
+               ]
+               self.comb += self._r_locked.status.eq(self.locked)
+
+               # sychronize pix+pix2x reset
+               pix_rst_n = 1
+               for i in range(2):
+                       new_pix_rst_n = Signal()
+                       self.specials += Instance("FDCE", i_D=pix_rst_n, i_CE=1, i_C=ClockSignal("pix"),
+                               i_CLR=~locked_async, o_Q=new_pix_rst_n)
+                       pix_rst_n = new_pix_rst_n
+               self.comb += self._cd_pix.rst.eq(~pix_rst_n), self._cd_pix2x.rst.eq(~pix_rst_n)
diff --git a/misoclib/dvisampler/common.py b/misoclib/dvisampler/common.py
new file mode 100644 (file)
index 0000000..f053237
--- /dev/null
@@ -0,0 +1,3 @@
+control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
+channel_layout = [("d", 8), ("c", 2), ("de", 1)]
+frame_layout = [("parity", 1), ("r", 8), ("g", 8), ("b", 8)]
diff --git a/misoclib/dvisampler/datacapture.py b/misoclib/dvisampler/datacapture.py
new file mode 100644 (file)
index 0000000..d788843
--- /dev/null
@@ -0,0 +1,186 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg, PulseSynchronizer
+from migen.bank.description import *
+
+class DataCapture(Module, AutoCSR):
+       def __init__(self, pad_p, pad_n, ntbits):
+               self.serdesstrobe = Signal()
+               self.d = Signal(10)
+
+               self._r_dly_ctl = CSR(6)
+               self._r_dly_busy = CSRStatus(2)
+               self._r_phase = CSRStatus(2)
+               self._r_phase_reset = CSR()
+
+               ###
+
+               # IO
+               pad_se = Signal()
+               self.specials += Instance("IBUFDS", i_I=pad_p, i_IB=pad_n, o_O=pad_se)
+
+               pad_delayed_master = Signal()
+               pad_delayed_slave = Signal()
+               delay_inc = Signal()
+               delay_ce = Signal()
+               delay_master_cal = Signal()
+               delay_master_rst = Signal()
+               delay_master_busy = Signal()
+               delay_slave_cal = Signal()
+               delay_slave_rst = Signal()
+               delay_slave_busy = Signal()
+               self.specials += Instance("IODELAY2",
+                       p_SERDES_MODE="MASTER",
+                       p_DELAY_SRC="IDATAIN", p_IDELAY_TYPE="DIFF_PHASE_DETECTOR",
+                       p_COUNTER_WRAPAROUND="STAY_AT_LIMIT", p_DATA_RATE="SDR",
+
+                       i_IDATAIN=pad_se, o_DATAOUT=pad_delayed_master,
+                       i_CLK=ClockSignal("pix2x"), i_IOCLK0=ClockSignal("pix10x"),
+
+                       i_INC=delay_inc, i_CE=delay_ce,
+                       i_CAL=delay_master_cal, i_RST=delay_master_rst, o_BUSY=delay_master_busy,
+                       i_T=1)
+               self.specials += Instance("IODELAY2",
+                       p_SERDES_MODE="SLAVE",
+                       p_DELAY_SRC="IDATAIN", p_IDELAY_TYPE="DIFF_PHASE_DETECTOR",
+                       p_COUNTER_WRAPAROUND="WRAPAROUND", p_DATA_RATE="SDR",
+
+                       i_IDATAIN=pad_se, o_DATAOUT=pad_delayed_slave,
+                       i_CLK=ClockSignal("pix2x"), i_IOCLK0=ClockSignal("pix10x"),
+
+                       i_INC=delay_inc, i_CE=delay_ce,
+                       i_CAL=delay_slave_cal, i_RST=delay_slave_rst, o_BUSY=delay_slave_busy,
+                       i_T=1)
+
+               dsr2 = Signal(5)
+               pd_valid = Signal()
+               pd_incdec = Signal()
+               pd_edge = Signal()
+               pd_cascade = Signal()
+               self.specials += Instance("ISERDES2",
+                       p_SERDES_MODE="MASTER",
+                       p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=5,
+                       p_INTERFACE_TYPE="RETIMED",
+
+                       i_D=pad_delayed_master,
+                       o_Q4=dsr2[4], o_Q3=dsr2[3], o_Q2=dsr2[2], o_Q1=dsr2[1],
+
+                       i_BITSLIP=0, i_CE0=1, i_RST=0,
+                       i_CLK0=ClockSignal("pix10x"), i_CLKDIV=ClockSignal("pix2x"),
+                       i_IOCE=self.serdesstrobe,
+
+                       o_VALID=pd_valid, o_INCDEC=pd_incdec,
+                       i_SHIFTIN=pd_edge, o_SHIFTOUT=pd_cascade)
+               self.specials += Instance("ISERDES2",
+                       p_SERDES_MODE="SLAVE",
+                       p_BITSLIP_ENABLE="FALSE", p_DATA_RATE="SDR", p_DATA_WIDTH=5,
+                       p_INTERFACE_TYPE="RETIMED",
+
+                       i_D=pad_delayed_slave,
+                       o_Q4=dsr2[0],
+
+                       i_BITSLIP=0, i_CE0=1, i_RST=0,
+                       i_CLK0=ClockSignal("pix10x"), i_CLKDIV=ClockSignal("pix2x"),
+                       i_IOCE=self.serdesstrobe,
+
+                       i_SHIFTIN=pd_cascade, o_SHIFTOUT=pd_edge)
+
+               # Phase error accumulator
+               lateness = Signal(ntbits, reset=2**(ntbits - 1))
+               too_late = Signal()
+               too_early = Signal()
+               reset_lateness = Signal()
+               self.comb += [
+                       too_late.eq(lateness == (2**ntbits - 1)),
+                       too_early.eq(lateness == 0)
+               ]
+               self.sync.pix2x += [
+                       If(reset_lateness,
+                               lateness.eq(2**(ntbits - 1))
+                       ).Elif(~delay_master_busy & ~delay_slave_busy & ~too_late & ~too_early,
+                               If(pd_valid &  pd_incdec, lateness.eq(lateness - 1)),
+                               If(pd_valid & ~pd_incdec, lateness.eq(lateness + 1))
+                       )
+               ]
+
+               # Delay control
+               self.submodules.delay_master_done = PulseSynchronizer("pix2x", "sys")
+               delay_master_pending = Signal()
+               self.sync.pix2x += [
+                       self.delay_master_done.i.eq(0),
+                       If(~delay_master_pending,
+                               If(delay_master_cal | delay_ce, delay_master_pending.eq(1))
+                       ).Else(
+                               If(~delay_master_busy,
+                                       self.delay_master_done.i.eq(1),
+                                       delay_master_pending.eq(0)
+                               )
+                       )
+               ]
+               self.submodules.delay_slave_done = PulseSynchronizer("pix2x", "sys")
+               delay_slave_pending = Signal()
+               self.sync.pix2x += [
+                       self.delay_slave_done.i.eq(0),
+                       If(~delay_slave_pending,
+                               If(delay_slave_cal | delay_ce, delay_slave_pending.eq(1))
+                       ).Else(
+                               If(~delay_slave_busy,
+                                       self.delay_slave_done.i.eq(1),
+                                       delay_slave_pending.eq(0)
+                               )
+                       )
+               ]
+
+               self.submodules.do_delay_master_cal = PulseSynchronizer("sys", "pix2x")
+               self.submodules.do_delay_master_rst = PulseSynchronizer("sys", "pix2x")
+               self.submodules.do_delay_slave_cal = PulseSynchronizer("sys", "pix2x")
+               self.submodules.do_delay_slave_rst = PulseSynchronizer("sys", "pix2x")
+               self.submodules.do_delay_inc = PulseSynchronizer("sys", "pix2x")
+               self.submodules.do_delay_dec = PulseSynchronizer("sys", "pix2x")
+               self.comb += [
+                       delay_master_cal.eq(self.do_delay_master_cal.o),
+                       delay_master_rst.eq(self.do_delay_master_rst.o),
+                       delay_slave_cal.eq(self.do_delay_slave_cal.o),
+                       delay_slave_rst.eq(self.do_delay_slave_rst.o),
+                       delay_inc.eq(self.do_delay_inc.o),
+                       delay_ce.eq(self.do_delay_inc.o | self.do_delay_dec.o),
+               ]
+
+               sys_delay_master_pending = Signal()
+               self.sync += [
+                       If(self.do_delay_master_cal.i | self.do_delay_inc.i | self.do_delay_dec.i,
+                               sys_delay_master_pending.eq(1)
+                       ).Elif(self.delay_master_done.o,
+                               sys_delay_master_pending.eq(0)
+                       )
+               ]
+               sys_delay_slave_pending = Signal()
+               self.sync += [
+                       If(self.do_delay_slave_cal.i | self.do_delay_inc.i | self.do_delay_dec.i,
+                               sys_delay_slave_pending.eq(1)
+                       ).Elif(self.delay_slave_done.o,
+                               sys_delay_slave_pending.eq(0)
+                       )
+               ]
+
+               self.comb += [
+                       self.do_delay_master_cal.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[0]),
+                       self.do_delay_master_rst.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[1]),
+                       self.do_delay_slave_cal.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[2]),
+                       self.do_delay_slave_rst.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[3]),
+                       self.do_delay_inc.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[4]),
+                       self.do_delay_dec.i.eq(self._r_dly_ctl.re & self._r_dly_ctl.r[5]),
+                       self._r_dly_busy.status.eq(Cat(sys_delay_master_pending, sys_delay_slave_pending))
+               ]
+
+               # Phase detector control
+               self.specials += MultiReg(Cat(too_late, too_early), self._r_phase.status)
+               self.submodules.do_reset_lateness = PulseSynchronizer("sys", "pix2x")
+               self.comb += [
+                       reset_lateness.eq(self.do_reset_lateness.o),
+                       self.do_reset_lateness.i.eq(self._r_phase_reset.re)
+               ]
+
+               # 5:10 deserialization
+               dsr = Signal(10)
+               self.sync.pix2x += dsr.eq(Cat(dsr[5:], dsr2))
+               self.sync.pix += self.d.eq(dsr)
diff --git a/misoclib/dvisampler/debug.py b/misoclib/dvisampler/debug.py
new file mode 100644 (file)
index 0000000..555d3ee
--- /dev/null
@@ -0,0 +1,46 @@
+from migen.fhdl.std import *
+from migen.genlib.fifo import AsyncFIFO
+from migen.genlib.record import layout_len
+from migen.bank.description import AutoCSR
+from migen.actorlib import structuring, dma_lasmi, spi
+
+from misoclib.dvisampler.edid import EDID
+from misoclib.dvisampler.clocking import Clocking
+from misoclib.dvisampler.datacapture import DataCapture
+
+class RawDVISampler(Module, AutoCSR):
+       def __init__(self, pads, asmiport):
+               self.submodules.edid = EDID(pads)
+               self.submodules.clocking = Clocking(pads)
+
+               invert = False
+               try:
+                       s = getattr(pads, "data0")
+               except AttributeError:
+                       s = getattr(pads, "data0_n")
+                       invert = True
+               self.submodules.data0_cap = DataCapture(8, invert)
+               self.comb += [
+                       self.data0_cap.pad.eq(s),
+                       self.data0_cap.serdesstrobe.eq(self.clocking.serdesstrobe)
+               ]
+
+               fifo = RenameClockDomains(AsyncFIFO(10, 256),
+                       {"write": "pix", "read": "sys"})
+               self.submodules += fifo
+               self.comb += [
+                       fifo.din.eq(self.data0_cap.d),
+                       fifo.we.eq(1)
+               ]
+
+               pack_factor = asmiport.hub.dw//16
+               self.submodules.packer = structuring.Pack([("word", 10), ("pad", 6)], pack_factor)
+               self.submodules.cast = structuring.Cast(self.packer.source.payload.layout, asmiport.hub.dw)
+               self.submodules.dma = spi.DMAWriteController(dma_lasmi.Writer(lasmim), spi.MODE_SINGLE_SHOT)
+               self.comb += [
+                       self.packer.sink.stb.eq(fifo.readable),
+                       fifo.re.eq(self.packer.sink.ack),
+                       self.packer.sink.payload.word.eq(fifo.dout),
+                       self.packer.source.connect_flat(self.cast.sink),
+                       self.cast.source.connect_flat(self.dma.data)
+               ]
diff --git a/misoclib/dvisampler/decoding.py b/misoclib/dvisampler/decoding.py
new file mode 100644 (file)
index 0000000..73a6718
--- /dev/null
@@ -0,0 +1,24 @@
+from migen.fhdl.std import *
+from migen.genlib.record import Record
+
+from misoclib.dvisampler.common import control_tokens, channel_layout
+
+class Decoding(Module):
+       def __init__(self):
+               self.valid_i = Signal()
+               self.input = Signal(10)
+               self.valid_o = Signal()
+               self.output = Record(channel_layout)
+
+               ###
+
+               self.sync.pix += self.output.de.eq(1)
+               for i, t in enumerate(control_tokens):
+                       self.sync.pix += If(self.input == t,
+                               self.output.de.eq(0),
+                               self.output.c.eq(i)
+                       )
+               self.sync.pix += self.output.d[0].eq(self.input[0] ^ self.input[9])
+               for i in range(1, 8):
+                       self.sync.pix += self.output.d[i].eq(self.input[i] ^ self.input[i-1] ^ ~self.input[8])
+               self.sync.pix += self.valid_o.eq(self.valid_i)
diff --git a/misoclib/dvisampler/dma.py b/misoclib/dvisampler/dma.py
new file mode 100644 (file)
index 0000000..f98f97e
--- /dev/null
@@ -0,0 +1,156 @@
+from migen.fhdl.std import *
+from migen.genlib.fsm import FSM, NextState
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+from migen.flow.actor import *
+from migen.actorlib import dma_lasmi
+
+from misoclib.dvisampler.common import frame_layout
+
+# Slot status: EMPTY=0 LOADED=1 PENDING=2
+class _Slot(Module, AutoCSR):
+       def __init__(self, addr_bits, alignment_bits):
+               self.ev_source = EventSourceLevel()
+               self.address = Signal(addr_bits)
+               self.address_valid = Signal()
+               self.address_done = Signal()
+
+               self._r_status = CSRStorage(2, write_from_dev=True)
+               self._r_address = CSRStorage(addr_bits + alignment_bits, alignment_bits=alignment_bits)
+
+               ###
+
+               self.comb += [
+                       self.address.eq(self._r_address.storage),
+                       self.address_valid.eq(self._r_status.storage[0]),
+                       self._r_status.dat_w.eq(2),
+                       self._r_status.we.eq(self.address_done),
+                       self.ev_source.trigger.eq(self._r_status.storage[1])
+               ]
+
+class _SlotArray(Module, AutoCSR):
+       def __init__(self, nslots, addr_bits, alignment_bits):
+               self.submodules.ev = EventManager()
+               self.address = Signal(addr_bits)
+               self.address_valid = Signal()
+               self.address_done = Signal()
+
+               ###
+
+               slots = [_Slot(addr_bits, alignment_bits) for i in range(nslots)]
+               for n, slot in enumerate(slots):
+                       setattr(self.submodules, "slot"+str(n), slot)
+                       setattr(self.ev, "slot"+str(n), slot.ev_source)
+               self.ev.finalize()
+
+               change_slot = Signal()
+               current_slot = Signal(max=nslots)
+               self.sync += If(change_slot, [If(slot.address_valid, current_slot.eq(n)) for n, slot in reversed(list(enumerate(slots)))])
+               self.comb += change_slot.eq(~self.address_valid | self.address_done)
+
+               self.comb += [
+                       self.address.eq(Array(slot.address for slot in slots)[current_slot]),
+                       self.address_valid.eq(Array(slot.address_valid for slot in slots)[current_slot])
+               ]
+               self.comb += [slot.address_done.eq(self.address_done & (current_slot == n)) for n, slot in enumerate(slots)]
+
+class DMA(Module):
+       def __init__(self, lasmim, nslots):
+               bus_aw = lasmim.aw
+               bus_dw = lasmim.dw
+               alignment_bits = bits_for(bus_dw//8) - 1
+
+               self.frame = Sink(frame_layout)
+               self._r_frame_size = CSRStorage(bus_aw + alignment_bits, alignment_bits=alignment_bits)
+               self.submodules._slot_array = _SlotArray(nslots, bus_aw, alignment_bits)
+               self.ev = self._slot_array.ev
+
+               ###
+
+               # start of frame detection
+               sof = Signal()
+               parity_r = Signal()
+               self.sync += If(self.frame.stb & self.frame.ack, parity_r.eq(self.frame.payload.parity))
+               self.comb += sof.eq(parity_r ^ self.frame.payload.parity)
+
+               # address generator + maximum memory word count to prevent DMA buffer overrun
+               reset_words = Signal()
+               count_word = Signal()
+               last_word = Signal()
+               current_address = Signal(bus_aw)
+               mwords_remaining = Signal(bus_aw)
+               self.comb += last_word.eq(mwords_remaining == 1)
+               self.sync += [
+                       If(reset_words,
+                               current_address.eq(self._slot_array.address),
+                               mwords_remaining.eq(self._r_frame_size.storage)
+                       ).Elif(count_word,
+                               current_address.eq(current_address + 1),
+                               mwords_remaining.eq(mwords_remaining - 1)
+                       )
+               ]
+
+               # pack pixels into memory words
+               write_pixel = Signal()
+               last_pixel = Signal()
+               cur_memory_word = Signal(bus_dw)
+               encoded_pixel = Signal(32)
+               self.comb += [
+                       encoded_pixel.eq(Cat(
+                               self.frame.payload.b[6:], self.frame.payload.b,
+                               self.frame.payload.g[6:], self.frame.payload.g,
+                               self.frame.payload.r[6:], self.frame.payload.r))
+               ]
+               pack_factor = bus_dw//32
+               assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2
+               pack_counter = Signal(max=pack_factor)
+               self.comb += last_pixel.eq(pack_counter == (pack_factor - 1))
+               self.sync += If(write_pixel,
+                               [If(pack_counter == (pack_factor-i-1),
+                                       cur_memory_word[32*i:32*(i+1)].eq(encoded_pixel)) for i in range(pack_factor)],
+                               pack_counter.eq(pack_counter + 1)
+                       )
+
+               # bus accessor
+               self.submodules._bus_accessor = dma_lasmi.Writer(lasmim)
+               self.comb += [
+                       self._bus_accessor.address_data.payload.a.eq(current_address),
+                       self._bus_accessor.address_data.payload.d.eq(cur_memory_word)
+               ]
+
+               # control FSM
+               fsm = FSM()
+               self.submodules += fsm
+
+               fsm.act("WAIT_SOF",
+                       reset_words.eq(1),
+                       self.frame.ack.eq(~self._slot_array.address_valid | ~sof),
+                       If(self._slot_array.address_valid & sof & self.frame.stb, NextState("TRANSFER_PIXEL"))
+               )
+               fsm.act("TRANSFER_PIXEL",
+                       self.frame.ack.eq(1),
+                       If(self.frame.stb,
+                               write_pixel.eq(1),
+                               If(last_pixel, NextState("TO_MEMORY"))
+                       )
+               )
+               fsm.act("TO_MEMORY",
+                       self._bus_accessor.address_data.stb.eq(1),
+                       If(self._bus_accessor.address_data.ack,
+                               count_word.eq(1),
+                               If(last_word,
+                                       NextState("EOF")
+                               ).Else(
+                                       NextState("TRANSFER_PIXEL")
+                               )
+                       )
+               )
+               fsm.act("EOF",
+                       If(~self._bus_accessor.busy,
+                               self._slot_array.address_done.eq(1),
+                               NextState("WAIT_SOF")
+                       )
+               )
+
+       def get_csrs(self):
+               return [self._r_frame_size] + self._slot_array.get_csrs()
diff --git a/misoclib/dvisampler/edid.py b/misoclib/dvisampler/edid.py
new file mode 100644 (file)
index 0000000..b4afb4e
--- /dev/null
@@ -0,0 +1,189 @@
+from migen.fhdl.std import *
+from migen.fhdl.specials import Tristate
+from migen.genlib.cdc import MultiReg
+from migen.genlib.fsm import FSM, NextState
+from migen.genlib.misc import chooser
+from migen.bank.description import CSRStorage, CSRStatus, AutoCSR
+
+_default_edid = [
+       0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x3D, 0x17, 0x32, 0x12, 0x2A, 0x6A, 0xBF, 0x00,
+       0x05, 0x17, 0x01, 0x03, 0x80, 0x28, 0x1E, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x2E, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
+       0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0xB2, 0x0C, 0x00, 0x40, 0x41, 0x00, 0x26, 0x30, 0x18, 0x88,
+       0x36, 0x00, 0x28, 0x1E, 0x00, 0x00, 0x00, 0x1E, 0x00, 0x00, 0x00, 0xFC, 0x00, 0x4D, 0x31, 0x20,
+       0x44, 0x56, 0x49, 0x20, 0x6D, 0x69, 0x78, 0x65, 0x72, 0x0A, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10,
+       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x34,
+]
+
+class EDID(Module, AutoCSR):
+       def __init__(self, pads, default=_default_edid):
+               self._r_hpd_notif = CSRStatus()
+               self._r_hpd_en = CSRStorage()
+               self.specials.mem = Memory(8, 128, init=default)
+
+               ###
+
+               # HPD
+               if hasattr(pads, "hpd_notif"):
+                       self.specials += MultiReg(pads.hpd_notif, self._r_hpd_notif.status)
+               else:
+                       self.comb += self._r_hpd_notif.status.eq(1)
+               if hasattr(pads, "hpd_en"):
+                       self.comb += pads.hpd_en.eq(self._r_hpd_en.storage)
+
+               # EDID
+               scl_raw = Signal()
+               sda_i = Signal()
+               sda_drv = Signal()
+               _sda_drv_reg = Signal()
+               _sda_i_async = Signal()
+               self.sync += _sda_drv_reg.eq(sda_drv)
+               self.specials += [
+                       MultiReg(pads.scl, scl_raw),
+                       Tristate(pads.sda, 0, _sda_drv_reg, _sda_i_async),
+                       MultiReg(_sda_i_async, sda_i)
+               ]
+
+               scl_i = Signal()
+               samp_count = Signal(6)
+               samp_carry = Signal()
+               self.sync += [
+                       Cat(samp_count, samp_carry).eq(samp_count + 1),
+                       If(samp_carry, scl_i.eq(scl_raw))
+               ]
+
+               scl_r = Signal()
+               sda_r = Signal()
+               scl_rising = Signal()
+               sda_rising = Signal()
+               sda_falling = Signal()
+               self.sync += [
+                       scl_r.eq(scl_i),
+                       sda_r.eq(sda_i)
+               ]
+               self.comb += [
+                       scl_rising.eq(scl_i & ~scl_r),
+                       sda_rising.eq(sda_i & ~sda_r),
+                       sda_falling.eq(~sda_i & sda_r)
+               ]
+
+               start = Signal()
+               self.comb += start.eq(scl_i & sda_falling)
+
+               din = Signal(8)
+               counter = Signal(max=9)
+               self.sync += [
+                       If(start, counter.eq(0)),
+                       If(scl_rising,
+                               If(counter == 8,
+                                       counter.eq(0)
+                               ).Else(
+                                       counter.eq(counter + 1),
+                                       din.eq(Cat(sda_i, din[:7]))
+                               )
+                       )
+               ]
+
+               is_read = Signal()
+               update_is_read = Signal()
+               self.sync += If(update_is_read, is_read.eq(din[0]))
+
+               offset_counter = Signal(max=128)
+               oc_load = Signal()
+               oc_inc = Signal()
+               self.sync += [
+                       If(oc_load,
+                               offset_counter.eq(din)
+                       ).Elif(oc_inc,
+                               offset_counter.eq(offset_counter + 1)
+                       )
+               ]
+               rdport = self.mem.get_port()
+               self.specials += rdport
+               self.comb += rdport.adr.eq(offset_counter)
+               data_bit = Signal()
+
+               zero_drv = Signal()
+               data_drv = Signal()
+               self.comb += If(zero_drv, sda_drv.eq(1)).Elif(data_drv, sda_drv.eq(~data_bit))
+
+               data_drv_en = Signal()
+               data_drv_stop = Signal()
+               self.sync += If(data_drv_en, data_drv.eq(1)).Elif(data_drv_stop, data_drv.eq(0))
+               self.sync += If(data_drv_en, chooser(rdport.dat_r, counter, data_bit, 8, reverse=True))
+
+               fsm = FSM()
+               self.submodules += fsm
+       
+               fsm.act("WAIT_START")
+               fsm.act("RCV_ADDRESS",
+                       If(counter == 8,
+                               If(din[1:] == 0x50,
+                                       update_is_read.eq(1),
+                                       NextState("ACK_ADDRESS0")
+                               ).Else(
+                                       NextState("WAIT_START")
+                               )
+                       )
+               )
+               fsm.act("ACK_ADDRESS0",
+                       If(~scl_i, NextState("ACK_ADDRESS1"))
+               )
+               fsm.act("ACK_ADDRESS1",
+                       zero_drv.eq(1),
+                       If(scl_i, NextState("ACK_ADDRESS2"))
+               )
+               fsm.act("ACK_ADDRESS2",
+                       zero_drv.eq(1),
+                       If(~scl_i,
+                               If(is_read,
+                                       NextState("READ")
+                               ).Else(
+                                       NextState("RCV_OFFSET")
+                               )
+                       )
+               )
+
+               fsm.act("RCV_OFFSET",
+                       If(counter == 8,
+                               oc_load.eq(1),
+                               NextState("ACK_OFFSET0")
+                       )
+               )
+               fsm.act("ACK_OFFSET0",
+                       If(~scl_i, NextState("ACK_OFFSET1"))
+               )
+               fsm.act("ACK_OFFSET1",
+                       zero_drv.eq(1),
+                       If(scl_i, NextState("ACK_OFFSET2"))
+               )
+               fsm.act("ACK_OFFSET2",
+                       zero_drv.eq(1),
+                       If(~scl_i, NextState("RCV_ADDRESS"))
+               )
+
+               fsm.act("READ",
+                       If(~scl_i,
+                               If(counter == 8,
+                                       data_drv_stop.eq(1),
+                                       NextState("ACK_READ")
+                               ).Else(
+                                       data_drv_en.eq(1)
+                               )
+                       )
+               )
+               fsm.act("ACK_READ",
+                       If(scl_rising,
+                               oc_inc.eq(1),
+                               If(sda_i,
+                                       NextState("WAIT_START")
+                               ).Else(
+                                       NextState("READ")
+                               )
+                       )
+               )
+
+               for state in fsm.actions.keys():
+                       fsm.act(state, If(start, NextState("RCV_ADDRESS")))
+                       fsm.act(state, If(~self._r_hpd_en.storage, NextState("WAIT_START")))
diff --git a/misoclib/dvisampler/wer.py b/misoclib/dvisampler/wer.py
new file mode 100644 (file)
index 0000000..6be35ab
--- /dev/null
@@ -0,0 +1,59 @@
+from migen.fhdl.std import *
+from migen.bank.description import *
+from migen.genlib.misc import optree
+from migen.genlib.cdc import PulseSynchronizer
+
+from misoclib.dvisampler.common import control_tokens
+
+class WER(Module, AutoCSR):
+       def __init__(self, period_bits=24):
+               self.data = Signal(10)
+               self._r_update = CSR()
+               self._r_value = CSRStatus(period_bits)
+
+               ###
+
+               # pipeline stage 1
+               # we ignore the 10th (inversion) bit, as it is independent of the transition minimization
+               data_r = Signal(9)
+               self.sync.pix += data_r.eq(self.data[:9])
+
+               # pipeline stage 2
+               transitions = Signal(8)
+               self.comb += [transitions[i].eq(data_r[i] ^ data_r[i+1]) for i in range(8)]
+               transition_count = Signal(max=9)
+               self.sync.pix += transition_count.eq(optree("+", [transitions[i] for i in range(8)]))
+
+               is_control = Signal()
+               self.sync.pix += is_control.eq(optree("|", [data_r == ct for ct in control_tokens]))
+
+               # pipeline stage 3
+               is_error = Signal()
+               self.sync.pix += is_error.eq((transition_count > 4) & ~is_control)
+
+               # counter
+               period_counter = Signal(period_bits)
+               period_done = Signal()
+               self.sync.pix += Cat(period_counter, period_done).eq(period_counter + 1)
+
+               wer_counter = Signal(period_bits)
+               wer_counter_r = Signal(period_bits)
+               wer_counter_r_updated = Signal()
+               self.sync.pix += [
+                       wer_counter_r_updated.eq(period_done),
+                       If(period_done,
+                               wer_counter_r.eq(wer_counter),
+                               wer_counter.eq(0)
+                       ).Elif(is_error,
+                               wer_counter.eq(wer_counter + 1)
+                       )
+               ]
+
+               # sync to system clock domain
+               wer_counter_sys = Signal(period_bits)
+               self.submodules.ps_counter = PulseSynchronizer("pix", "sys")
+               self.comb += self.ps_counter.i.eq(wer_counter_r_updated)
+               self.sync += If(self.ps_counter.o, wer_counter_sys.eq(wer_counter_r))
+
+               # register interface
+               self.sync += If(self._r_update.re, self._r_value.status.eq(wer_counter_sys))
diff --git a/misoclib/framebuffer/__init__.py b/misoclib/framebuffer/__init__.py
new file mode 100644 (file)
index 0000000..ec49dba
--- /dev/null
@@ -0,0 +1,110 @@
+from migen.fhdl.std import *
+from migen.flow.actor import *
+from migen.flow.network import *
+from migen.bank.description import CSRStorage, AutoCSR
+from migen.actorlib import dma_lasmi, structuring, sim, spi
+
+from misoclib.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG
+from misoclib.framebuffer.phy import Driver
+
+class Framebuffer(Module, AutoCSR):
+       def __init__(self, pads_vga, pads_dvi, lasmim, simulation=False):
+               pack_factor = lasmim.dw//(2*bpp)
+               packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
+               
+               self._enable = CSRStorage()
+               self.fi = FrameInitiator()
+               self.dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
+               self.driver = Driver(pads_vga, pads_dvi)
+
+               cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
+               unpack = structuring.Unpack(pack_factor, pixel_layout)
+               vtg = VTG()
+               
+               g = DataFlowGraph()
+               g.add_connection(self.fi, vtg, sink_ep="timing")
+               g.add_connection(self.dma, cast)
+               g.add_connection(cast, unpack)
+               g.add_connection(unpack, vtg, sink_ep="pixels")
+               g.add_connection(vtg, self.driver)
+               self.submodules += CompositeActor(g)
+
+               self.comb += [
+                       self.fi.trigger.eq(self._enable.storage),
+                       self.dma.generator.trigger.eq(self._enable.storage),
+               ]
+
+class Blender(PipelinedActor, AutoCSR):
+       def __init__(self, nimages, latency):
+               sink_layout = [("i"+str(i), pixel_layout) for i in range(nimages)]
+               self.sink = Sink(sink_layout)
+               self.source = Source(pixel_layout)
+               factors = []
+               for i in range(nimages):
+                       name = "f"+str(i)
+                       csr = CSRStorage(8, name=name)
+                       setattr(self, name, csr)
+                       factors.append(csr.storage)
+               PipelinedActor.__init__(self, latency)
+
+               ###
+
+               sink_registered = Record(sink_layout)
+               self.sync += If(self.pipe_ce, sink_registered.eq(self.sink.payload))
+
+               imgs = [getattr(sink_registered, "i"+str(i)) for i in range(nimages)]
+               outval = Record(pixel_layout)
+               for e in pixel_layout:
+                       name = e[0]
+                       inpixs = [getattr(img, name) for img in imgs]
+                       outpix = getattr(outval, name)
+                       for component in ["r", "g", "b"]:
+                               incomps = [getattr(pix, component) for pix in inpixs]
+                               outcomp = getattr(outpix, component)
+                               outcomp_full = Signal(19)
+                               self.comb += [
+                                       outcomp_full.eq(sum(incomp*factor for incomp, factor in zip(incomps, factors))),
+                                       If(outcomp_full[18],
+                                               outcomp.eq(2**10 - 1) # saturate on overflow
+                                       ).Else(
+                                               outcomp.eq(outcomp_full[8:18])
+                                       )
+                               ]
+
+               pipe_stmts = []
+               for i in range(latency-1):
+                       new_outval = Record(pixel_layout)
+                       pipe_stmts.append(new_outval.eq(outval))
+                       outval = new_outval
+               self.sync += If(self.pipe_ce, pipe_stmts)
+               self.comb += self.source.payload.eq(outval)
+
+class MixFramebuffer(Module, AutoCSR):
+       def __init__(self, pads_vga, pads_dvi, *lasmims, blender_latency=5):
+               pack_factor = lasmims[0].dw//(2*bpp)
+               packed_pixels = structuring.pack_layout(pixel_layout, pack_factor)
+               
+               self._enable = CSRStorage()
+               self.fi = FrameInitiator()
+               self.blender = Blender(len(lasmims), blender_latency)
+               self.driver = Driver(pads_vga, pads_dvi)
+               self.comb += self.fi.trigger.eq(self._enable.storage)
+
+               g = DataFlowGraph()
+               for n, lasmim in enumerate(lasmims):
+                       dma = spi.DMAReadController(dma_lasmi.Reader(lasmim), spi.MODE_EXTERNAL, length_reset=640*480*4)
+                       cast = structuring.Cast(lasmim.dw, packed_pixels, reverse_to=True)
+                       unpack = structuring.Unpack(pack_factor, pixel_layout)
+
+                       g.add_connection(dma, cast)
+                       g.add_connection(cast, unpack)
+                       g.add_connection(unpack, self.blender, sink_subr=["i"+str(n)])
+
+                       self.comb += dma.generator.trigger.eq(self._enable.storage)
+                       setattr(self, "dma"+str(n), dma)
+
+               vtg = VTG()
+               g.add_connection(self.fi, vtg, sink_ep="timing")
+               g.add_connection(self.blender, vtg, sink_ep="pixels")
+               g.add_connection(vtg, self.driver)
+               self.submodules += CompositeActor(g)
diff --git a/misoclib/framebuffer/dvi.py b/misoclib/framebuffer/dvi.py
new file mode 100644 (file)
index 0000000..9c08507
--- /dev/null
@@ -0,0 +1,219 @@
+from migen.fhdl.std import *
+from migen.genlib.misc import optree
+
+control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011]
+
+class Encoder(Module):
+       def __init__(self):
+               self.d = Signal(8)
+               self.c = Signal(2)
+               self.de = Signal()
+
+               self.out = Signal(10)
+
+               ###
+
+               # stage 1 - count number of 1s in data
+               d = Signal(8)
+               n1d = Signal(max=9)
+               self.sync += [
+                       n1d.eq(optree("+", [self.d[i] for i in range(8)])),
+                       d.eq(self.d)
+               ]
+
+               # stage 2 - add 9th bit
+               q_m = Signal(9)
+               q_m8_n = Signal()
+               self.comb += q_m8_n.eq((n1d > 4) | ((n1d == 4) & ~d[0]))
+               for i in range(8):
+                       if i:
+                               curval = curval ^ d[i] ^ q_m8_n 
+                       else:
+                               curval = d[0]           
+                       self.sync += q_m[i].eq(curval)
+               self.sync += q_m[8].eq(~q_m8_n)
+
+               # stage 3 - count number of 1s and 0s in q_m[:8]
+               q_m_r = Signal(9)
+               n0q_m = Signal(max=9)
+               n1q_m = Signal(max=9)
+               self.sync += [
+                       n0q_m.eq(optree("+", [~q_m[i] for i in range(8)])),
+                       n1q_m.eq(optree("+", [q_m[i] for i in range(8)])),
+                       q_m_r.eq(q_m)
+               ]
+
+               # stage 4 - final encoding
+               cnt = Signal((6, True))
+
+               s_c = self.c
+               s_de = self.de
+               for p in range(3):
+                       new_c = Signal(2)
+                       new_de = Signal()
+                       self.sync += new_c.eq(s_c), new_de.eq(s_de)
+                       s_c, s_de = new_c, new_de
+
+               self.sync += If(s_de,
+                               If((cnt == 0) | (n1q_m == n0q_m),
+                                       self.out[9].eq(~q_m_r[8]),
+                                       self.out[8].eq(q_m_r[8]),
+                                       If(q_m_r[8],
+                                               self.out[:8].eq(q_m_r[:8]),
+                                               cnt.eq(cnt + n1q_m - n0q_m)
+                                       ).Else(
+                                               self.out[:8].eq(~q_m_r[:8]),
+                                               cnt.eq(cnt + n0q_m - n1q_m)
+                                       )
+                               ).Else(
+                                       If((~cnt[5] & (n1q_m > n0q_m)) | (cnt[5] & (n0q_m > n1q_m)),
+                                               self.out[9].eq(1),
+                                               self.out[8].eq(q_m_r[8]),
+                                               self.out[:8].eq(~q_m_r[:8]),
+                                               cnt.eq(cnt + Cat(0, q_m_r[8]) + n0q_m - n1q_m)
+                                       ).Else(
+                                               self.out[9].eq(0),
+                                               self.out[8].eq(q_m_r[8]),
+                                               self.out[:8].eq(q_m_r[:8]),
+                                               cnt.eq(cnt - Cat(0, ~q_m_r[8]) + n1q_m - n0q_m)
+                                       )
+                               )
+                       ).Else(
+                               self.out.eq(Array(control_tokens)[s_c]),
+                               cnt.eq(0)
+                       )
+
+class _EncoderSerializer(Module):
+       def __init__(self, serdesstrobe, pad_p, pad_n):
+               self.submodules.encoder = RenameClockDomains(Encoder(), "pix")
+               self.d, self.c, self.de = self.encoder.d, self.encoder.c, self.encoder.de
+
+               ###
+
+               # 2X soft serialization
+               ed_2x = Signal(5)
+               self.sync.pix2x += ed_2x.eq(Mux(ClockSignal("pix"), self.encoder.out[:5], self.encoder.out[5:]))
+
+               # 5X hard serialization
+               cascade_di = Signal()
+               cascade_do = Signal()
+               cascade_ti = Signal()
+               cascade_to = Signal()
+               pad_se = Signal()
+               self.specials += [
+                       Instance("OSERDES2",
+                               p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
+                               p_SERDES_MODE="MASTER", p_OUTPUT_MODE="DIFFERENTIAL",
+
+                               o_OQ=pad_se,
+                               i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
+                               i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
+                               i_D1=ed_2x[4], i_D2=0, i_D3=0, i_D4=0,
+                               i_T1=0, i_T2=0, i_T3=0, i_T4=0,
+                               i_TRAIN=0, i_TCE=1,
+                               i_SHIFTIN1=1, i_SHIFTIN2=1,
+                               i_SHIFTIN3=cascade_do, i_SHIFTIN4=cascade_to,
+                               o_SHIFTOUT1=cascade_di, o_SHIFTOUT2=cascade_ti),
+                       Instance("OSERDES2",
+                               p_DATA_WIDTH=5, p_DATA_RATE_OQ="SDR", p_DATA_RATE_OT="SDR",
+                               p_SERDES_MODE="SLAVE", p_OUTPUT_MODE="DIFFERENTIAL",
+
+                               i_OCE=1, i_IOCE=serdesstrobe, i_RST=0,
+                               i_CLK0=ClockSignal("pix10x"), i_CLK1=0, i_CLKDIV=ClockSignal("pix2x"),
+                               i_D1=ed_2x[0], i_D2=ed_2x[1], i_D3=ed_2x[2], i_D4=ed_2x[3],
+                               i_T1=0, i_T2=0, i_T3=0, i_T4=0,
+                               i_TRAIN=0, i_TCE=1,
+                               i_SHIFTIN1=cascade_di, i_SHIFTIN2=cascade_ti,
+                               i_SHIFTIN3=1, i_SHIFTIN4=1,
+                               o_SHIFTOUT3=cascade_do, o_SHIFTOUT4=cascade_to),
+                       Instance("OBUFDS", i_I=pad_se, o_O=pad_p, o_OB=pad_n)
+               ]
+
+
+class PHY(Module):
+       def __init__(self, serdesstrobe, pads):
+               self.hsync = Signal()
+               self.vsync = Signal()
+               self.de = Signal()
+               self.r = Signal(8)
+               self.g = Signal(8)
+               self.b = Signal(8)
+
+               ###
+
+               self.submodules.es0 = _EncoderSerializer(serdesstrobe, pads.data0_p, pads.data0_n)
+               self.submodules.es1 = _EncoderSerializer(serdesstrobe, pads.data1_p, pads.data1_n)
+               self.submodules.es2 = _EncoderSerializer(serdesstrobe, pads.data2_p, pads.data2_n)
+               self.comb += [
+                       self.es0.d.eq(self.r),
+                       self.es1.d.eq(self.g),
+                       self.es2.d.eq(self.b),
+                       self.es0.c.eq(Cat(self.hsync, self.vsync)),
+                       self.es1.c.eq(0),
+                       self.es2.c.eq(0),
+                       self.es0.de.eq(self.de),
+                       self.es1.de.eq(self.de),
+                       self.es2.de.eq(self.de),
+               ]
+
+class _EncoderTB(Module):
+       def __init__(self, inputs):
+               self.outs = []
+               self._iter_inputs = iter(inputs)
+               self._end_cycle = None
+               self.submodules.dut = Encoder()
+               self.comb += self.dut.de.eq(1)
+
+       def do_simulation(self, s):
+               if self._end_cycle is None:
+                       try:
+                               nv = next(self._iter_inputs)
+                       except StopIteration:
+                               self._end_cycle = s.cycle_counter + 4
+                       else:
+                               s.wr(self.dut.d, nv)
+               if s.cycle_counter == self._end_cycle:
+                       s.interrupt = True
+               if s.cycle_counter > 4:
+                       self.outs.append(s.rd(self.dut.out))
+
+def _bit(i, n):
+       return (i >> n) & 1
+
+def _decode_tmds(b):
+       try:
+               c = control_tokens.index(b)
+               de = False
+       except ValueError:
+               c = 0
+               de = True
+       vsync = bool(c & 2)
+       hsync = bool(c & 1)
+
+       value = _bit(b, 0) ^ _bit(b, 9)
+       for i in range(1, 8):
+               value |= (_bit(b, i) ^ _bit(b, i-1) ^ (~_bit(b, 8) & 1)) << i
+
+       return de, hsync, vsync, value
+
+if __name__ == "__main__":
+       from migen.sim.generic import Simulator
+       from random import Random
+       
+       rng = Random(788)
+       test_list = [rng.randrange(256) for i in range(500)]
+       tb = _EncoderTB(test_list)
+       Simulator(tb).run()
+
+       check = [_decode_tmds(out)[3] for out in tb.outs]
+       assert(check == test_list)
+       
+       nb0 = 0
+       nb1 = 0
+       for out in tb.outs:
+               for i in range(10):
+                       if _bit(out, i):
+                               nb1 += 1
+                       else:
+                               nb0 += 1
+       print("0/1: {}/{} ({:.2f})".format(nb0, nb1, nb0/nb1))
diff --git a/misoclib/framebuffer/format.py b/misoclib/framebuffer/format.py
new file mode 100644 (file)
index 0000000..7e42245
--- /dev/null
@@ -0,0 +1,113 @@
+from migen.fhdl.std import *
+from migen.flow.actor import *
+from migen.bank.description import CSRStorage
+from migen.actorlib import spi
+
+_hbits = 11
+_vbits = 12
+
+bpp = 32
+bpc = 10
+pixel_layout_s = [
+       ("pad", bpp-3*bpc),
+       ("r", bpc),
+       ("g", bpc),
+       ("b", bpc)
+]
+pixel_layout = [
+       ("p0", pixel_layout_s),
+       ("p1", pixel_layout_s)
+]
+
+bpc_phy = 8
+phy_layout_s = [
+       ("r", bpc_phy),
+       ("g", bpc_phy),
+       ("b", bpc_phy)
+]
+phy_layout = [
+       ("hsync", 1),
+       ("vsync", 1),
+       ("de", 1),
+       ("p0", phy_layout_s),
+       ("p1", phy_layout_s)
+]
+
+class FrameInitiator(spi.SingleGenerator):
+       def __init__(self):
+               layout = [
+                       ("hres", _hbits, 640, 1),
+                       ("hsync_start", _hbits, 656, 1),
+                       ("hsync_end", _hbits, 752, 1),
+                       ("hscan", _hbits, 800, 1),
+                       
+                       ("vres", _vbits, 480),
+                       ("vsync_start", _vbits, 492),
+                       ("vsync_end", _vbits, 494),
+                       ("vscan", _vbits, 525)
+               ]
+               spi.SingleGenerator.__init__(self, layout, spi.MODE_EXTERNAL)
+
+class VTG(Module):
+       def __init__(self):
+               self.timing = Sink([
+                               ("hres", _hbits),
+                               ("hsync_start", _hbits),
+                               ("hsync_end", _hbits),
+                               ("hscan", _hbits),
+                               ("vres", _vbits),
+                               ("vsync_start", _vbits),
+                               ("vsync_end", _vbits),
+                               ("vscan", _vbits)])
+               self.pixels = Sink(pixel_layout)
+               self.phy = Source(phy_layout)
+               self.busy = Signal()
+
+               hactive = Signal()
+               vactive = Signal()
+               active = Signal()
+               
+               generate_en = Signal()
+               hcounter = Signal(_hbits)
+               vcounter = Signal(_vbits)
+               
+               skip = bpc - bpc_phy
+               self.comb += [
+                       active.eq(hactive & vactive),
+                       If(active,
+                               [getattr(getattr(self.phy.payload, p), c).eq(getattr(getattr(self.pixels.payload, p), c)[skip:])
+                                       for p in ["p0", "p1"] for c in ["r", "g", "b"]],
+                               self.phy.payload.de.eq(1)
+                       ),
+                       
+                       generate_en.eq(self.timing.stb & (~active | self.pixels.stb)),
+                       self.pixels.ack.eq(self.phy.ack & active),
+                       self.phy.stb.eq(generate_en),
+                       self.busy.eq(generate_en)
+               ]
+               tp = self.timing.payload
+               self.sync += [
+                       self.timing.ack.eq(0),
+                       If(generate_en & self.phy.ack,
+                               hcounter.eq(hcounter + 1),
+                       
+                               If(hcounter == 0, hactive.eq(1)),
+                               If(hcounter == tp.hres, hactive.eq(0)),
+                               If(hcounter == tp.hsync_start, self.phy.payload.hsync.eq(1)),
+                               If(hcounter == tp.hsync_end, self.phy.payload.hsync.eq(0)),
+                               If(hcounter == tp.hscan,
+                                       hcounter.eq(0),
+                                       If(vcounter == tp.vscan,
+                                               vcounter.eq(0),
+                                               self.timing.ack.eq(1)
+                                       ).Else(
+                                               vcounter.eq(vcounter + 1)
+                                       )
+                               ),
+                               
+                               If(vcounter == 0, vactive.eq(1)),
+                               If(vcounter == tp.vres, vactive.eq(0)),
+                               If(vcounter == tp.vsync_start, self.phy.payload.vsync.eq(1)),
+                               If(vcounter == tp.vsync_end, self.phy.payload.vsync.eq(0))
+                       )
+               ]
diff --git a/misoclib/framebuffer/phy.py b/misoclib/framebuffer/phy.py
new file mode 100644 (file)
index 0000000..ff71e69
--- /dev/null
@@ -0,0 +1,197 @@
+from migen.fhdl.std import *
+from migen.genlib.fifo import AsyncFIFO
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+from migen.flow.actor import *
+
+from misoclib.framebuffer.format import bpc_phy, phy_layout
+from misoclib.framebuffer import dvi
+
+class _FIFO(Module):
+       def __init__(self):
+               self.phy = Sink(phy_layout)
+               self.busy = Signal()
+               
+               self.pix_hsync = Signal()
+               self.pix_vsync = Signal()
+               self.pix_de = Signal()
+               self.pix_r = Signal(bpc_phy)
+               self.pix_g = Signal(bpc_phy)
+               self.pix_b = Signal(bpc_phy)
+       
+               ###
+
+               fifo = RenameClockDomains(AsyncFIFO(phy_layout, 512),
+                       {"write": "sys", "read": "pix"})
+               self.submodules += fifo
+               self.comb += [
+                       self.phy.ack.eq(fifo.writable),
+                       fifo.we.eq(self.phy.stb),
+                       fifo.din.eq(self.phy.payload),
+                       self.busy.eq(0)
+               ]
+
+               pix_parity = Signal()
+               self.sync.pix += [
+                       pix_parity.eq(~pix_parity),
+                       self.pix_hsync.eq(fifo.dout.hsync),
+                       self.pix_vsync.eq(fifo.dout.vsync),
+                       self.pix_de.eq(fifo.dout.de),
+                       If(pix_parity,
+                               self.pix_r.eq(fifo.dout.p1.r),
+                               self.pix_g.eq(fifo.dout.p1.g),
+                               self.pix_b.eq(fifo.dout.p1.b)
+                       ).Else(
+                               self.pix_r.eq(fifo.dout.p0.r),
+                               self.pix_g.eq(fifo.dout.p0.g),
+                               self.pix_b.eq(fifo.dout.p0.b)
+                       )
+               ]
+               self.comb += fifo.re.eq(pix_parity)
+
+# This assumes a 50MHz base clock
+class _Clocking(Module, AutoCSR):
+       def __init__(self, pads_vga, pads_dvi):
+               self._r_cmd_data = CSRStorage(10)
+               self._r_send_cmd_data = CSR()
+               self._r_send_go = CSR()
+               self._r_status = CSRStatus(4)
+
+               self.clock_domains.cd_pix = ClockDomain(reset_less=True)
+               if pads_dvi is not None:
+                       self.clock_domains.cd_pix2x = ClockDomain(reset_less=True)
+                       self.clock_domains.cd_pix10x = ClockDomain(reset_less=True)
+                       self.serdesstrobe = Signal()
+
+               ###
+
+               # Generate 1x pixel clock
+               clk_pix_unbuffered = Signal()
+               pix_progdata = Signal()
+               pix_progen = Signal()
+               pix_progdone = Signal()
+               pix_locked = Signal()
+               self.specials += Instance("DCM_CLKGEN",
+                       p_CLKFXDV_DIVIDE=2, p_CLKFX_DIVIDE=4, p_CLKFX_MD_MAX=1.0, p_CLKFX_MULTIPLY=2,
+                       p_CLKIN_PERIOD=20.0, p_SPREAD_SPECTRUM="NONE", p_STARTUP_WAIT="FALSE",
+               
+                       i_CLKIN=ClockSignal("base50"), o_CLKFX=clk_pix_unbuffered,
+                       i_PROGCLK=ClockSignal(), i_PROGDATA=pix_progdata, i_PROGEN=pix_progen,
+                       o_PROGDONE=pix_progdone, o_LOCKED=pix_locked,
+                       i_FREEZEDCM=0, i_RST=ResetSignal())
+
+               remaining_bits = Signal(max=11)
+               transmitting = Signal()
+               self.comb += transmitting.eq(remaining_bits != 0)
+               sr = Signal(10)
+               self.sync += [
+                       If(self._r_send_cmd_data.re,
+                               remaining_bits.eq(10),
+                               sr.eq(self._r_cmd_data.storage)
+                       ).Elif(transmitting,
+                               remaining_bits.eq(remaining_bits - 1),
+                               sr.eq(sr[1:])
+                       )
+               ]
+               self.comb += [
+                       pix_progdata.eq(transmitting & sr[0]),
+                       pix_progen.eq(transmitting | self._r_send_go.re)
+               ]
+
+               # enforce gap between commands
+               busy_counter = Signal(max=14)
+               busy = Signal()
+               self.comb += busy.eq(busy_counter != 0)
+               self.sync += If(self._r_send_cmd_data.re,
+                               busy_counter.eq(13)
+                       ).Elif(busy,
+                               busy_counter.eq(busy_counter - 1)
+                       )
+
+               mult_locked = Signal()
+               self.comb += self._r_status.status.eq(Cat(busy, pix_progdone, pix_locked, mult_locked))
+
+               # Clock multiplication and buffering
+               if pads_dvi is None:
+                       # Just buffer 1x pixel clock
+                       self.specials += Instance("BUFG", i_I=clk_pix_unbuffered, o_O=self.cd_pix.clk)
+                       self.comb += mult_locked.eq(pix_locked)
+               else:
+                       # Route unbuffered 1x pixel clock to PLL
+                       # Generate 1x, 2x and 10x IO pixel clocks
+                       clkfbout = Signal()
+                       pll_locked = Signal()
+                       pll_clk0 = Signal()
+                       pll_clk1 = Signal()
+                       pll_clk2 = Signal()
+                       locked_async = Signal()
+                       self.specials += [
+                               Instance("PLL_BASE",
+                                       p_CLKIN_PERIOD=26.7,
+                                       p_CLKFBOUT_MULT=20,
+                                       p_CLKOUT0_DIVIDE=2,  # pix10x
+                                       p_CLKOUT1_DIVIDE=10, # pix2x
+                                       p_CLKOUT2_DIVIDE=20, # pix
+                                       p_COMPENSATION="INTERNAL",
+                                       
+                                       i_CLKIN=clk_pix_unbuffered,
+                                       o_CLKOUT0=pll_clk0, o_CLKOUT1=pll_clk1, o_CLKOUT2=pll_clk2,
+                                       o_CLKFBOUT=clkfbout, i_CLKFBIN=clkfbout,
+                                       o_LOCKED=pll_locked, i_RST=~pix_locked),
+                               Instance("BUFPLL", p_DIVIDE=5,
+                                       i_PLLIN=pll_clk0, i_GCLK=ClockSignal("pix2x"), i_LOCKED=pll_locked,
+                                       o_IOCLK=self.cd_pix10x.clk, o_LOCK=locked_async, o_SERDESSTROBE=self.serdesstrobe),
+                               Instance("BUFG", i_I=pll_clk1, o_O=self.cd_pix2x.clk),
+                               Instance("BUFG", name="dviout_pix_bufg", i_I=pll_clk2, o_O=self.cd_pix.clk),
+                               MultiReg(locked_async, mult_locked, "sys")
+                       ]
+
+               # Drive VGA/DVI clock pads
+               if pads_vga is not None:
+                       self.specials += Instance("ODDR2",
+                               p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
+                               o_Q=pads_vga.clk,
+                               i_C0=ClockSignal("pix"),
+                               i_C1=~ClockSignal("pix"),
+                               i_CE=1, i_D0=1, i_D1=0,
+                               i_R=0, i_S=0)
+               if pads_dvi is not None:
+                       dvi_clk_se = Signal()
+                       self.specials += Instance("ODDR2",
+                               p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC",
+                               o_Q=dvi_clk_se,
+                               i_C0=ClockSignal("pix"),
+                               i_C1=~ClockSignal("pix"),
+                               i_CE=1, i_D0=1, i_D1=0,
+                               i_R=0, i_S=0)
+                       self.specials += Instance("OBUFDS", i_I=dvi_clk_se,
+                               o_O=pads_dvi.clk_p, o_OB=pads_dvi.clk_n)
+
+class Driver(Module, AutoCSR):
+       def __init__(self, pads_vga, pads_dvi):
+               fifo = _FIFO()
+               self.submodules += fifo
+               self.phy = fifo.phy
+               self.busy = fifo.busy
+
+               self.submodules.clocking = _Clocking(pads_vga, pads_dvi)
+
+               if pads_vga is not None:
+                       self.comb += [
+                               pads_vga.hsync_n.eq(~fifo.pix_hsync),
+                               pads_vga.vsync_n.eq(~fifo.pix_vsync),
+                               pads_vga.r.eq(fifo.pix_r),
+                               pads_vga.g.eq(fifo.pix_g),
+                               pads_vga.b.eq(fifo.pix_b),
+                               pads_vga.psave_n.eq(1)
+                       ]
+               if pads_dvi is not None:
+                       self.submodules.dvi_phy = dvi.PHY(self.clocking.serdesstrobe, pads_dvi)
+                       self.comb += [
+                               self.dvi_phy.hsync.eq(fifo.pix_hsync),
+                               self.dvi_phy.vsync.eq(fifo.pix_vsync),
+                               self.dvi_phy.de.eq(fifo.pix_de),
+                               self.dvi_phy.r.eq(fifo.pix_r),
+                               self.dvi_phy.g.eq(fifo.pix_g),
+                               self.dvi_phy.b.eq(fifo.pix_b)
+                       ]
diff --git a/misoclib/gpio/__init__.py b/misoclib/gpio/__init__.py
new file mode 100644 (file)
index 0000000..d02332e
--- /dev/null
@@ -0,0 +1,19 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+
+class GPIOIn(Module, AutoCSR):
+       def __init__(self, signal):
+               self._r_in = CSRStatus(flen(signal))
+               self.specials += MultiReg(signal, self._r_in.status)
+
+class GPIOOut(Module, AutoCSR):
+       def __init__(self, signal):
+               self._r_out = CSRStorage(flen(signal))
+               self.comb += signal.eq(self._r_out.storage)
+
+class Blinker(Module):
+       def __init__(self, signal, divbits=26):
+               counter = Signal(divbits)
+               self.comb += signal.eq(counter[divbits-1])
+               self.sync += counter.eq(counter + 1)
diff --git a/misoclib/identifier/__init__.py b/misoclib/identifier/__init__.py
new file mode 100644 (file)
index 0000000..ca792fd
--- /dev/null
@@ -0,0 +1,29 @@
+import re
+
+from migen.fhdl.std import *
+from migen.bank.description import *
+
+def encode_version(version):
+       match = re.match("(\d+)\.(\d+)(\.(\d+))?(rc(\d+))?", version, re.IGNORECASE)
+       r = (int(match.group(1)) << 12) | (int(match.group(2)) << 8)
+       subminor = match.group(4)
+       rc = match.group(6)
+       if subminor:
+               r |= int(subminor) << 4
+       if rc:
+               r |= int(rc)
+       return r
+
+class Identifier(Module, AutoCSR):
+       def __init__(self, sysid, version, frequency):
+               self._r_sysid = CSRStatus(16)
+               self._r_version = CSRStatus(16)
+               self._r_frequency = CSRStatus(32)
+               
+               ###
+
+               self.comb += [
+                       self._r_sysid.status.eq(sysid),
+                       self._r_version.status.eq(encode_version(version)),
+                       self._r_frequency.status.eq(frequency)
+               ]
diff --git a/misoclib/lasmicon/__init__.py b/misoclib/lasmicon/__init__.py
new file mode 100644 (file)
index 0000000..60819cc
--- /dev/null
@@ -0,0 +1,52 @@
+from collections import namedtuple
+
+from migen.fhdl.std import *
+from migen.bus import dfi, lasmibus
+
+from misoclib.lasmicon.refresher import *
+from misoclib.lasmicon.bankmachine import *
+from misoclib.lasmicon.multiplexer import *
+
+PhySettings = namedtuple("PhySettings", "memtype dfi_d nphases rdphase wrphase rdcmdphase wrcmdphase cl read_latency write_latency")
+
+class GeomSettings(namedtuple("_GeomSettings", "bank_a row_a col_a")):
+       def __init__(self, *args, **kwargs):
+               self.mux_a = max(self.row_a, self.col_a)
+
+TimingSettings = namedtuple("TimingSettings", "tRP tRCD tWR tWTR tREFI tRFC" \
+       " req_queue_size read_time write_time")
+
+class LASMIcon(Module):
+       def __init__(self, phy_settings, geom_settings, timing_settings):
+               if phy_settings.memtype in ["SDR"]:
+                       burst_length = phy_settings.nphases*1 # command multiplication*SDR
+               elif phy_settings.memtype in ["DDR", "LPDDR", "DDR2", "DDR3"]:
+                       burst_length = phy_settings.nphases*2 # command multiplication*DDR
+               address_align = log2_int(burst_length)
+
+               self.dfi = dfi.Interface(geom_settings.mux_a,
+                       geom_settings.bank_a,
+                       phy_settings.dfi_d,
+                       phy_settings.nphases)
+               self.lasmic = lasmibus.Interface(
+                       aw=geom_settings.row_a + geom_settings.col_a - address_align,
+                       dw=phy_settings.dfi_d*phy_settings.nphases,
+                       nbanks=2**geom_settings.bank_a,
+                       req_queue_size=timing_settings.req_queue_size,
+                       read_latency=phy_settings.read_latency+1,
+                       write_latency=phy_settings.write_latency+1)
+               self.nrowbits = geom_settings.col_a - address_align
+       
+               ###
+
+               self.submodules.refresher = Refresher(geom_settings.mux_a, geom_settings.bank_a,
+                       timing_settings.tRP, timing_settings.tREFI, timing_settings.tRFC)
+               self.submodules.bank_machines = [BankMachine(geom_settings, timing_settings, address_align, i,
+                               getattr(self.lasmic, "bank"+str(i)))
+                       for i in range(2**geom_settings.bank_a)]
+               self.submodules.multiplexer = Multiplexer(phy_settings, geom_settings, timing_settings,
+                       self.bank_machines, self.refresher,
+                       self.dfi, self.lasmic)
+
+       def get_csrs(self):
+               return self.multiplexer.get_csrs()
diff --git a/misoclib/lasmicon/bankmachine.py b/misoclib/lasmicon/bankmachine.py
new file mode 100644 (file)
index 0000000..a956811
--- /dev/null
@@ -0,0 +1,144 @@
+from migen.fhdl.std import *
+from migen.genlib.roundrobin import *
+from migen.genlib.fsm import FSM, NextState
+from migen.genlib.misc import optree
+from migen.genlib.fifo import SyncFIFO
+
+from misoclib.lasmicon.multiplexer import *
+
+class _AddressSlicer:
+       def __init__(self, col_a, address_align):
+               self.col_a = col_a
+               self.address_align = address_align
+       
+       def row(self, address):
+               split = self.col_a - self.address_align
+               if isinstance(address, int):
+                       return address >> split
+               else:
+                       return address[split:]
+               
+       def col(self, address):
+               split = self.col_a - self.address_align
+               if isinstance(address, int):
+                       return (address & (2**split - 1)) << self.address_align
+               else:
+                       return Cat(Replicate(0, self.address_align), address[:split])
+       
+class BankMachine(Module):
+       def __init__(self, geom_settings, timing_settings, address_align, bankn, req):
+               self.refresh_req = Signal()
+               self.refresh_gnt = Signal()
+               self.cmd = CommandRequestRW(geom_settings.mux_a, geom_settings.bank_a)
+
+               ###
+
+               # Request FIFO
+               self.submodules.req_fifo = SyncFIFO([("we", 1), ("adr", flen(req.adr))], timing_settings.req_queue_size)
+               self.comb += [
+                       self.req_fifo.din.we.eq(req.we),
+                       self.req_fifo.din.adr.eq(req.adr),
+                       self.req_fifo.we.eq(req.stb),
+                       req.req_ack.eq(self.req_fifo.writable),
+
+                       self.req_fifo.re.eq(req.dat_ack),
+                       req.lock.eq(self.req_fifo.readable)
+               ]
+               reqf = self.req_fifo.dout
+
+               slicer = _AddressSlicer(geom_settings.col_a, address_align)
+               
+               # Row tracking
+               has_openrow = Signal()
+               openrow = Signal(geom_settings.row_a)
+               hit = Signal()
+               self.comb += hit.eq(openrow == slicer.row(reqf.adr))
+               track_open = Signal()
+               track_close = Signal()
+               self.sync += [
+                       If(track_open,
+                               has_openrow.eq(1),
+                               openrow.eq(slicer.row(reqf.adr))
+                       ),
+                       If(track_close,
+                               has_openrow.eq(0)
+                       )
+               ]
+               
+               # Address generation
+               s_row_adr = Signal()
+               self.comb += [
+                       self.cmd.ba.eq(bankn),
+                       If(s_row_adr,
+                               self.cmd.a.eq(slicer.row(reqf.adr))
+                       ).Else(
+                               self.cmd.a.eq(slicer.col(reqf.adr))
+                       )
+               ]
+               
+               # Respect write-to-precharge specification
+               precharge_ok = Signal()
+               t_unsafe_precharge = 2 + timing_settings.tWR - 1
+               unsafe_precharge_count = Signal(max=t_unsafe_precharge+1)
+               self.comb += precharge_ok.eq(unsafe_precharge_count == 0)
+               self.sync += [
+                       If(self.cmd.stb & self.cmd.ack & self.cmd.is_write,
+                               unsafe_precharge_count.eq(t_unsafe_precharge)
+                       ).Elif(~precharge_ok,
+                               unsafe_precharge_count.eq(unsafe_precharge_count-1)
+                       )
+               ]
+               
+               # Control and command generation FSM
+               fsm = FSM()
+               self.submodules += fsm
+               fsm.act("REGULAR",
+                       If(self.refresh_req,
+                               NextState("REFRESH")
+                       ).Elif(self.req_fifo.readable,
+                               If(has_openrow,
+                                       If(hit,
+                                               # NB: write-to-read specification is enforced by multiplexer
+                                               self.cmd.stb.eq(1),
+                                               req.dat_ack.eq(self.cmd.ack),
+                                               self.cmd.is_read.eq(~reqf.we),
+                                               self.cmd.is_write.eq(reqf.we),
+                                               self.cmd.cas_n.eq(0),
+                                               self.cmd.we_n.eq(~reqf.we)
+                                       ).Else(
+                                               NextState("PRECHARGE")
+                                       )
+                               ).Else(
+                                       NextState("ACTIVATE")
+                               )
+                       )
+               )
+               fsm.act("PRECHARGE",
+                       # Notes:
+                       # 1. we are presenting the column address, A10 is always low
+                       # 2. since we always go to the ACTIVATE state, we do not need
+                       # to assert track_close.
+                       If(precharge_ok,
+                               self.cmd.stb.eq(1),
+                               If(self.cmd.ack, NextState("TRP")),
+                               self.cmd.ras_n.eq(0),
+                               self.cmd.we_n.eq(0),
+                               self.cmd.is_cmd.eq(1)
+                       )
+               )
+               fsm.act("ACTIVATE",
+                       s_row_adr.eq(1),
+                       track_open.eq(1),
+                       self.cmd.stb.eq(1),
+                       self.cmd.is_cmd.eq(1),
+                       If(self.cmd.ack, NextState("TRCD")),
+                       self.cmd.ras_n.eq(0)
+               )
+               fsm.act("REFRESH",
+                       self.refresh_gnt.eq(precharge_ok),
+                       track_close.eq(1),
+                       self.cmd.is_cmd.eq(1),
+                       If(~self.refresh_req, NextState("REGULAR"))
+               )
+               fsm.delayed_enter("TRP", "ACTIVATE", timing_settings.tRP-1)
+               fsm.delayed_enter("TRCD", "REGULAR", timing_settings.tRCD-1)
diff --git a/misoclib/lasmicon/multiplexer.py b/misoclib/lasmicon/multiplexer.py
new file mode 100644 (file)
index 0000000..2ca99c1
--- /dev/null
@@ -0,0 +1,210 @@
+from migen.fhdl.std import *
+from migen.genlib.roundrobin import *
+from migen.genlib.misc import optree
+from migen.genlib.fsm import FSM, NextState
+from migen.bank.description import AutoCSR
+
+from misoclib.lasmicon.perf import Bandwidth
+
+class CommandRequest:
+       def __init__(self, a, ba):
+               self.a = Signal(a)
+               self.ba = Signal(ba)
+               self.cas_n = Signal(reset=1)
+               self.ras_n = Signal(reset=1)
+               self.we_n = Signal(reset=1)
+
+class CommandRequestRW(CommandRequest):
+       def __init__(self, a, ba):
+               CommandRequest.__init__(self, a, ba)
+               self.stb = Signal()
+               self.ack = Signal()
+               self.is_cmd = Signal()
+               self.is_read = Signal()
+               self.is_write = Signal()
+
+class _CommandChooser(Module):
+       def __init__(self, requests):
+               self.want_reads = Signal()
+               self.want_writes = Signal()
+               self.want_cmds = Signal()
+               # NB: cas_n/ras_n/we_n are 1 when stb is inactive
+               self.cmd = CommandRequestRW(flen(requests[0].a), flen(requests[0].ba))
+       
+               ###
+
+               rr = RoundRobin(len(requests), SP_CE)
+               self.submodules += rr
+               
+               self.comb += [rr.request[i].eq(req.stb & ((req.is_cmd & self.want_cmds) | ((req.is_read == self.want_reads) | (req.is_write == self.want_writes))))
+                       for i, req in enumerate(requests)]
+               
+               stb = Signal()
+               self.comb += stb.eq(Array(req.stb for req in requests)[rr.grant])
+               for name in ["a", "ba", "is_read", "is_write", "is_cmd"]:
+                       choices = Array(getattr(req, name) for req in requests)
+                       self.comb += getattr(self.cmd, name).eq(choices[rr.grant])
+               for name in ["cas_n", "ras_n", "we_n"]:
+                       # we should only assert those signals when stb is 1
+                       choices = Array(getattr(req, name) for req in requests)
+                       self.comb += If(self.cmd.stb, getattr(self.cmd, name).eq(choices[rr.grant]))
+               self.comb += self.cmd.stb.eq(stb \
+                       & ((self.cmd.is_cmd & self.want_cmds) | ((self.cmd.is_read == self.want_reads) \
+                       & (self.cmd.is_write == self.want_writes))))
+               
+               self.comb += [If(self.cmd.stb & self.cmd.ack & (rr.grant == i), req.ack.eq(1))
+                       for i, req in enumerate(requests)]
+               self.comb += rr.ce.eq(self.cmd.ack)
+
+class _Steerer(Module):
+       def __init__(self, commands, dfi):
+               ncmd = len(commands)
+               nph = len(dfi.phases)
+               self.sel = [Signal(max=ncmd) for i in range(nph)]
+       
+               ###
+       
+               def stb_and(cmd, attr):
+                       if not hasattr(cmd, "stb"):
+                               return 0
+                       else:
+                               return cmd.stb & getattr(cmd, attr)
+               for phase, sel in zip(dfi.phases, self.sel):
+                       self.comb += [
+                               phase.cke.eq(1),
+                               phase.cs_n.eq(0)
+                       ]
+                       self.sync += [
+                               phase.address.eq(Array(cmd.a for cmd in commands)[sel]),
+                               phase.bank.eq(Array(cmd.ba for cmd in commands)[sel]),
+                               phase.cas_n.eq(Array(cmd.cas_n for cmd in commands)[sel]),
+                               phase.ras_n.eq(Array(cmd.ras_n for cmd in commands)[sel]),
+                               phase.we_n.eq(Array(cmd.we_n for cmd in commands)[sel]),
+                               phase.rddata_en.eq(Array(stb_and(cmd, "is_read") for cmd in commands)[sel]),
+                               phase.wrdata_en.eq(Array(stb_and(cmd, "is_write") for cmd in commands)[sel])
+                       ]
+
+class Multiplexer(Module, AutoCSR):
+       def __init__(self, phy_settings, geom_settings, timing_settings, bank_machines, refresher, dfi, lasmic):
+               assert(phy_settings.nphases == len(dfi.phases))
+       
+               # Command choosing
+               requests = [bm.cmd for bm in bank_machines]
+               choose_cmd = _CommandChooser(requests)
+               choose_req = _CommandChooser(requests)
+               self.comb += [
+                       choose_cmd.want_reads.eq(0),
+                       choose_cmd.want_writes.eq(0)
+               ]
+               if phy_settings.nphases == 1:
+                       self.comb += [
+                               choose_cmd.want_cmds.eq(1),
+                               choose_req.want_cmds.eq(1)
+                       ]       
+               self.submodules += choose_cmd, choose_req
+               
+               # Command steering
+               nop = CommandRequest(geom_settings.mux_a, geom_settings.bank_a)
+               commands = [nop, choose_cmd.cmd, choose_req.cmd, refresher.cmd] # nop must be 1st
+               (STEER_NOP, STEER_CMD, STEER_REQ, STEER_REFRESH) = range(4)
+               steerer = _Steerer(commands, dfi)
+               self.submodules += steerer
+               
+               # Read/write turnaround
+               read_available = Signal()
+               write_available = Signal()
+               self.comb += [
+                       read_available.eq(optree("|", [req.stb & req.is_read for req in requests])),
+                       write_available.eq(optree("|", [req.stb & req.is_write for req in requests]))
+               ]
+               
+               def anti_starvation(timeout):
+                       en = Signal()
+                       max_time = Signal()
+                       if timeout:
+                               t = timeout - 1
+                               time = Signal(max=t+1)
+                               self.comb += max_time.eq(time == 0)
+                               self.sync += If(~en,
+                                               time.eq(t)
+                                       ).Elif(~max_time,
+                                               time.eq(time - 1)
+                                       )
+                       else:
+                               self.comb += max_time.eq(0)
+                       return en, max_time
+               read_time_en, max_read_time = anti_starvation(timing_settings.read_time)
+               write_time_en, max_write_time = anti_starvation(timing_settings.write_time)
+               
+               # Refresh
+               self.comb += [bm.refresh_req.eq(refresher.req) for bm in bank_machines]
+               go_to_refresh = Signal()
+               self.comb += go_to_refresh.eq(optree("&", [bm.refresh_gnt for bm in bank_machines]))
+               
+               # Datapath
+               all_rddata = [p.rddata for p in dfi.phases]
+               all_wrdata = [p.wrdata for p in dfi.phases]
+               all_wrdata_mask = [p.wrdata_mask for p in dfi.phases]
+               self.comb += [
+                       lasmic.dat_r.eq(Cat(*all_rddata)),
+                       Cat(*all_wrdata).eq(lasmic.dat_w),
+                       Cat(*all_wrdata_mask).eq(~lasmic.dat_we)
+               ]
+               
+               # Control FSM
+               fsm = FSM()
+               self.submodules += fsm
+               
+               def steerer_sel(steerer, phy_settings, r_w_n):
+                       r = []
+                       for i in range(phy_settings.nphases):
+                               s = steerer.sel[i].eq(STEER_NOP)
+                               if r_w_n == "read":
+                                       if i == phy_settings.rdphase:
+                                               s = steerer.sel[i].eq(STEER_REQ)
+                                       elif i == phy_settings.rdcmdphase:
+                                               s = steerer.sel[i].eq(STEER_CMD)
+                               elif r_w_n == "write":
+                                       if i == phy_settings.wrphase:
+                                               s = steerer.sel[i].eq(STEER_REQ)
+                                       elif i == phy_settings.wrcmdphase:
+                                               s = steerer.sel[i].eq(STEER_CMD)
+                               else:
+                                       raise ValueError
+                               r.append(s)
+                       return r
+
+               fsm.act("READ",
+                       read_time_en.eq(1),
+                       choose_req.want_reads.eq(1),
+                       choose_cmd.cmd.ack.eq(1),
+                       choose_req.cmd.ack.eq(1),
+                       steerer_sel(steerer, phy_settings, "read"),
+                       If(write_available,
+                               # TODO: switch only after several cycles of ~read_available?
+                               If(~read_available | max_read_time, NextState("RTW"))
+                       ),
+                       If(go_to_refresh, NextState("REFRESH"))
+               )
+               fsm.act("WRITE",
+                       write_time_en.eq(1),
+                       choose_req.want_writes.eq(1),
+                       choose_cmd.cmd.ack.eq(1),
+                       choose_req.cmd.ack.eq(1),
+                       steerer_sel(steerer, phy_settings, "write"),
+                       If(read_available,
+                               If(~write_available | max_write_time, NextState("WTR"))
+                       ),
+                       If(go_to_refresh, NextState("REFRESH"))
+               )
+               fsm.act("REFRESH",
+                       steerer.sel[0].eq(STEER_REFRESH),
+                       If(~refresher.req, NextState("READ"))
+               )
+               fsm.delayed_enter("RTW", "WRITE", phy_settings.read_latency-1) # FIXME: reduce this, actual limit is around (cl+1)/nphases
+               fsm.delayed_enter("WTR", "READ", timing_settings.tWTR-1)
+               # FIXME: workaround for zero-delay loop simulation problem with Icarus Verilog
+               fsm.finalize()
+               self.comb += refresher.ack.eq(fsm.state == fsm.encoding["REFRESH"])
+
+               self.submodules.bandwidth = Bandwidth(choose_req.cmd)
diff --git a/misoclib/lasmicon/perf.py b/misoclib/lasmicon/perf.py
new file mode 100644 (file)
index 0000000..ec09c79
--- /dev/null
@@ -0,0 +1,44 @@
+from migen.fhdl.std import *
+from migen.bank.description import *
+
+class Bandwidth(Module, AutoCSR):
+       def __init__(self, cmd, period_bits=24):
+               self._r_update = CSR()
+               self._r_nreads = CSRStatus(period_bits)
+               self._r_nwrites = CSRStatus(period_bits)
+
+               ###
+
+               cmd_stb = Signal()
+               cmd_ack = Signal()
+               cmd_is_read = Signal()
+               cmd_is_write = Signal()
+               self.sync += [
+                       cmd_stb.eq(cmd.stb),
+                       cmd_ack.eq(cmd.ack),
+                       cmd_is_read.eq(cmd.is_read),
+                       cmd_is_write.eq(cmd.is_write)
+               ]
+
+               counter = Signal(period_bits)
+               period = Signal()
+               nreads = Signal(period_bits)
+               nwrites = Signal(period_bits)
+               nreads_r = Signal(period_bits)
+               nwrites_r = Signal(period_bits)
+               self.sync += [
+                       Cat(counter, period).eq(counter + 1),
+                       If(period,
+                               nreads_r.eq(nreads),
+                               nwrites_r.eq(nwrites),
+                               nreads.eq(0),
+                               nwrites.eq(0)
+                       ).Elif(cmd_stb & cmd_ack,
+                               If(cmd_is_read, nreads.eq(nreads + 1)),
+                               If(cmd_is_write, nwrites.eq(nwrites + 1)),
+                       ),
+                       If(self._r_update.re,
+                               self._r_nreads.status.eq(nreads_r),
+                               self._r_nwrites.status.eq(nwrites_r)
+                       )
+               ]
diff --git a/misoclib/lasmicon/refresher.py b/misoclib/lasmicon/refresher.py
new file mode 100644 (file)
index 0000000..aa493ae
--- /dev/null
@@ -0,0 +1,68 @@
+from migen.fhdl.std import *
+from migen.genlib.misc import timeline
+from migen.genlib.fsm import FSM
+
+from misoclib.lasmicon.multiplexer import *
+
+class Refresher(Module):
+       def __init__(self, a, ba, tRP, tREFI, tRFC):
+               self.req = Signal()
+               self.ack = Signal() # 1st command 1 cycle after assertion of ack
+               self.cmd = CommandRequest(a, ba)
+       
+               ###
+
+               # Refresh sequence generator:
+               # PRECHARGE ALL --(tRP)--> AUTO REFRESH --(tRFC)--> done
+               seq_start = Signal()
+               seq_done = Signal()
+               self.sync += [
+                       self.cmd.a.eq(2**10),
+                       self.cmd.ba.eq(0),
+                       self.cmd.cas_n.eq(1),
+                       self.cmd.ras_n.eq(1),
+                       self.cmd.we_n.eq(1),
+                       seq_done.eq(0)
+               ]
+               self.sync += timeline(seq_start, [
+                       (1, [
+                               self.cmd.ras_n.eq(0),
+                               self.cmd.we_n.eq(0)
+                       ]),
+                       (1+tRP, [
+                               self.cmd.cas_n.eq(0),
+                               self.cmd.ras_n.eq(0)
+                       ]),
+                       (1+tRP+tRFC, [
+                               seq_done.eq(1)
+                       ])
+               ])
+               
+               # Periodic refresh counter
+               counter = Signal(max=tREFI)
+               start = Signal()
+               self.sync += [
+                       start.eq(0),
+                       If(counter == 0,
+                               start.eq(1),
+                               counter.eq(tREFI - 1)
+                       ).Else(
+                               counter.eq(counter - 1)
+                       )
+               ]
+               
+               # Control FSM
+               fsm = FSM()
+               self.submodules += fsm
+               fsm.act("IDLE", If(start, NextState("WAIT_GRANT")))
+               fsm.act("WAIT_GRANT",
+                       self.req.eq(1),
+                       If(self.ack,
+                               seq_start.eq(1),
+                               NextState("WAIT_SEQ")
+                       )
+               )
+               fsm.act("WAIT_SEQ",
+                       self.req.eq(1),
+                       If(seq_done, NextState("IDLE"))
+               )
diff --git a/misoclib/lm32/__init__.py b/misoclib/lm32/__init__.py
new file mode 100644 (file)
index 0000000..35cf81c
--- /dev/null
@@ -0,0 +1,53 @@
+from migen.fhdl.std import *
+from migen.bus import wishbone
+
+class LM32(Module):
+       def __init__(self):
+               self.ibus = i = wishbone.Interface()
+               self.dbus = d = wishbone.Interface()
+               self.interrupt = Signal(32)
+               self.ext_break = Signal()
+
+               ###
+
+               i_adr_o = Signal(32)
+               d_adr_o = Signal(32)
+               self.specials += Instance("lm32_top",
+                       Instance.Input("clk_i", ClockSignal()),
+                       Instance.Input("rst_i", ResetSignal()),
+                       
+                       Instance.Input("interrupt", self.interrupt),
+                       #Instance.Input("ext_break", self.ext_break),
+               
+                       Instance.Output("I_ADR_O", i_adr_o),
+                       Instance.Output("I_DAT_O", i.dat_w),
+                       Instance.Output("I_SEL_O", i.sel),
+                       Instance.Output("I_CYC_O", i.cyc),
+                       Instance.Output("I_STB_O", i.stb),
+                       Instance.Output("I_WE_O", i.we),
+                       Instance.Output("I_CTI_O", i.cti),
+                       Instance.Output("I_LOCK_O"),
+                       Instance.Output("I_BTE_O", i.bte),
+                       Instance.Input("I_DAT_I", i.dat_r),
+                       Instance.Input("I_ACK_I", i.ack),
+                       Instance.Input("I_ERR_I", i.err),
+                       Instance.Input("I_RTY_I", 0),
+                       
+                       Instance.Output("D_ADR_O", d_adr_o),
+                       Instance.Output("D_DAT_O", d.dat_w),
+                       Instance.Output("D_SEL_O", d.sel),
+                       Instance.Output("D_CYC_O", d.cyc),
+                       Instance.Output("D_STB_O", d.stb),
+                       Instance.Output("D_WE_O", d.we),
+                       Instance.Output("D_CTI_O", d.cti),
+                       Instance.Output("D_LOCK_O"),
+                       Instance.Output("D_BTE_O", d.bte),
+                       Instance.Input("D_DAT_I", d.dat_r),
+                       Instance.Input("D_ACK_I", d.ack),
+                       Instance.Input("D_ERR_I", d.err),
+                       Instance.Input("D_RTY_I", 0))
+
+               self.comb += [
+                       self.ibus.adr.eq(i_adr_o[2:]),
+                       self.dbus.adr.eq(d_adr_o[2:])
+               ]
diff --git a/misoclib/memtest/__init__.py b/misoclib/memtest/__init__.py
new file mode 100644 (file)
index 0000000..9252229
--- /dev/null
@@ -0,0 +1,118 @@
+from migen.fhdl.std import *
+from migen.genlib.misc import optree
+from migen.bank.description import *
+from migen.actorlib import dma_lasmi
+from migen.actorlib.spi import *
+
+@DecorateModule(InsertReset)
+@DecorateModule(InsertCE)
+class LFSR(Module):
+       def __init__(self, n_out, n_state=31, taps=[27, 30]):
+               self.o = Signal(n_out)
+
+               ###
+
+               state = Signal(n_state)
+               curval = [state[i] for i in range(n_state)]
+               curval += [0]*(n_out - n_state)
+               for i in range(n_out):
+                       nv = ~optree("^", [curval[tap] for tap in taps])
+                       curval.insert(0, nv)
+                       curval.pop()
+
+               self.sync += [
+                       state.eq(Cat(*curval[:n_state])),
+                       self.o.eq(Cat(*curval))
+               ]
+
+def _print_lfsr_code():
+       from migen.fhdl import verilog
+       dut = LFSR(3, 4, [3, 2])
+       print(verilog.convert(dut, ios={dut.ce, dut.reset, dut.o}))
+
+class _LFSRTB(Module):
+       def __init__(self, *args, **kwargs):
+               self.submodules.lfsr = LFSR(*args, **kwargs)
+               self.comb += self.lfsr.ce.eq(1)
+
+       def do_simulation(self, s):
+               print("{0:032x}".format(s.rd(self.lfsr.o)))
+
+def _sim_lfsr():
+       from migen.sim.generic import Simulator
+       tb = _LFSRTB(128)
+       sim = Simulator(tb)
+       sim.run(20)
+
+memtest_magic = 0x361f
+
+class MemtestWriter(Module):
+       def __init__(self, lasmim):
+               self._r_magic = CSRStatus(16)
+               self._r_reset = CSR()
+               self._r_shoot = CSR()
+               self.submodules._dma = DMAWriteController(dma_lasmi.Writer(lasmim), MODE_EXTERNAL)
+
+               ###
+
+               self.comb += self._r_magic.status.eq(memtest_magic)
+
+               lfsr = LFSR(lasmim.dw)
+               self.submodules += lfsr
+               self.comb += lfsr.reset.eq(self._r_reset.re)
+
+               en = Signal()
+               en_counter = Signal(lasmim.aw)
+               self.comb += en.eq(en_counter != 0)
+               self.sync += [
+                       If(self._r_shoot.re,
+                               en_counter.eq(self._dma.length)
+                       ).Elif(lfsr.ce,
+                               en_counter.eq(en_counter - 1)
+                       )
+               ]
+
+               self.comb += [
+                       self._dma.trigger.eq(self._r_shoot.re),
+                       self._dma.data.stb.eq(en),
+                       lfsr.ce.eq(en & self._dma.data.ack),
+                       self._dma.data.payload.d.eq(lfsr.o)
+               ]
+
+       def get_csrs(self):
+               return [self._r_magic, self._r_reset, self._r_shoot] + self._dma.get_csrs()
+
+class MemtestReader(Module):
+       def __init__(self, lasmim):
+               self._r_magic = CSRStatus(16)
+               self._r_reset = CSR()
+               self._r_error_count = CSRStatus(lasmim.aw)
+               self.submodules._dma = DMAReadController(dma_lasmi.Reader(lasmim), MODE_SINGLE_SHOT)
+
+               ###
+
+               self.comb += self._r_magic.status.eq(memtest_magic)
+
+               lfsr = LFSR(lasmim.dw)
+               self.submodules += lfsr
+               self.comb += lfsr.reset.eq(self._r_reset.re)
+
+               self.comb += [
+                       lfsr.ce.eq(self._dma.data.stb),
+                       self._dma.data.ack.eq(1)
+               ]
+               err_cnt = self._r_error_count.status
+               self.sync += [
+                       If(self._r_reset.re,
+                               err_cnt.eq(0)
+                       ).Elif(self._dma.data.stb,
+                               If(self._dma.data.payload.d != lfsr.o, err_cnt.eq(err_cnt + 1))
+                       )
+               ]
+
+       def get_csrs(self):
+               return [self._r_magic, self._r_reset, self._r_error_count] + self._dma.get_csrs()
+
+if __name__ == "__main__":
+       _print_lfsr_code()
+       _sim_lfsr()
diff --git a/misoclib/minimac3/__init__.py b/misoclib/minimac3/__init__.py
new file mode 100644 (file)
index 0000000..37efdd4
--- /dev/null
@@ -0,0 +1,81 @@
+from migen.fhdl.std import *
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+from migen.bus import wishbone
+
+_count_width = 11
+
+class MiniMAC(Module, AutoCSR):
+       def __init__(self, pads):
+               # CPU interface
+               self._phy_reset = CSRStorage(reset=1)
+               self._rx_count_0 = CSRStatus(_count_width)
+               self._rx_count_1 = CSRStatus(_count_width)
+               self._tx_count = CSRStorage(_count_width, write_from_dev=True)
+               self._tx_start = CSR()
+               
+               self.submodules.ev = EventManager()
+               self.ev.rx0 = EventSourcePulse()
+               self.ev.rx1 = EventSourcePulse()
+               self.ev.tx = EventSourcePulse()
+               self.ev.finalize()
+               
+               self.membus = wishbone.Interface()
+               
+               ###
+
+               init = Signal(reset=1)
+               self.sync += init.eq(0)
+               rx_ready_0 = Signal()
+               rx_ready_1 = Signal()
+               rx_pending_0 = self.ev.rx0.pending
+               rx_pending_1 = self.ev.rx1.pending
+               rx_pending_0_r = Signal()
+               rx_pending_1_r = Signal()
+               self.comb += [
+                       pads.rst_n.eq(~self._phy_reset.storage),
+                       
+                       rx_ready_0.eq(init | (rx_pending_0_r & ~rx_pending_0)),
+                       rx_ready_1.eq(init | (rx_pending_1_r & ~rx_pending_1)),
+                       
+                       self._tx_count.dat_w.eq(0),
+                       self._tx_count.we.eq(self.ev.tx.trigger)
+               ]
+               self.sync += [
+                       rx_pending_0_r.eq(rx_pending_0),
+                       rx_pending_1_r.eq(rx_pending_1)
+               ]
+               self.specials += Instance("minimac3",
+                               Instance.Input("sys_clk", ClockSignal()),
+                               Instance.Input("sys_rst", ResetSignal()),
+
+                               Instance.Output("rx_done_0", self.ev.rx0.trigger),
+                               Instance.Output("rx_count_0", self._rx_count_0.status),
+                               Instance.Output("rx_done_1", self.ev.rx1.trigger),
+                               Instance.Output("rx_count_1", self._rx_count_1.status),
+                               Instance.Input("rx_ready_0", rx_ready_0),
+                               Instance.Input("rx_ready_1", rx_ready_1),
+
+                               Instance.Input("tx_start", self._tx_start.re),
+                               Instance.Input("tx_count", self._tx_count.storage),
+                               Instance.Output("tx_done", self.ev.tx.trigger),
+                               
+                               Instance.Input("wb_adr_i", self.membus.adr),
+                               Instance.Input("wb_dat_i", self.membus.dat_w),
+                               Instance.Input("wb_sel_i", self.membus.sel),
+                               Instance.Input("wb_stb_i", self.membus.stb),
+                               Instance.Input("wb_cyc_i", self.membus.cyc),
+                               Instance.Input("wb_we_i", self.membus.we),
+                               Instance.Output("wb_dat_o", self.membus.dat_r),
+                               Instance.Output("wb_ack_o", self.membus.ack),
+                               
+                               Instance.Input("phy_tx_clk", ClockSignal("eth_tx")),
+                               Instance.Output("phy_tx_data", pads.tx_data),
+                               Instance.Output("phy_tx_en", pads.tx_en),
+                               Instance.Output("phy_tx_er", pads.tx_er),
+                               Instance.Input("phy_rx_clk", ClockSignal("eth_rx")),
+                               Instance.Input("phy_rx_data", pads.rx_data),
+                               Instance.Input("phy_dv", pads.dv),
+                               Instance.Input("phy_rx_er", pads.rx_er),
+                               Instance.Input("phy_col", pads.col),
+                               Instance.Input("phy_crs", pads.crs))
diff --git a/misoclib/mxcrg/__init__.py b/misoclib/mxcrg/__init__.py
new file mode 100644 (file)
index 0000000..ab11001
--- /dev/null
@@ -0,0 +1,48 @@
+from fractions import Fraction
+
+from migen.fhdl.std import *
+
+class MXCRG(Module):
+       def __init__(self, pads, outfreq1x):
+               self.clock_domains.cd_sys = ClockDomain()
+               self.clock_domains.cd_sdram_half = ClockDomain()
+               self.clock_domains.cd_sdram_full_wr = ClockDomain()
+               self.clock_domains.cd_sdram_full_rd = ClockDomain()
+               self.clock_domains.cd_eth_rx = ClockDomain()
+               self.clock_domains.cd_eth_tx = ClockDomain()
+               self.clock_domains.cd_base50 = ClockDomain(reset_less=True)
+
+               self.clk4x_wr_strb = Signal()
+               self.clk4x_rd_strb = Signal()
+
+               ###
+               
+               infreq = 50*1000000
+               ratio = Fraction(outfreq1x)/Fraction(infreq)
+               in_period = float(Fraction(1000000000)/Fraction(infreq))
+
+               self.specials += Instance("mxcrg",
+                       Instance.Parameter("in_period", in_period),
+                       Instance.Parameter("f_mult", ratio.numerator),
+                       Instance.Parameter("f_div", ratio.denominator),
+                       Instance.Input("clk50_pad", pads.clk50),
+                       Instance.Input("trigger_reset", pads.trigger_reset),
+                       
+                       Instance.Input("eth_rx_clk_pad", pads.eth_rx_clk),
+                       Instance.Input("eth_tx_clk_pad", pads.eth_tx_clk),
+                       
+                       Instance.Output("sys_clk", self.cd_sys.clk),
+                       Instance.Output("sys_rst", self.cd_sys.rst),
+                       Instance.Output("clk2x_270", self.cd_sdram_half.clk),
+                       Instance.Output("clk4x_wr", self.cd_sdram_full_wr.clk),
+                       Instance.Output("clk4x_rd", self.cd_sdram_full_rd.clk),
+                       Instance.Output("eth_rx_clk", self.cd_eth_rx.clk),
+                       Instance.Output("eth_tx_clk", self.cd_eth_tx.clk),
+                       Instance.Output("base50_clk", self.cd_base50.clk),
+
+                       Instance.Output("clk4x_wr_strb", self.clk4x_wr_strb),
+                       Instance.Output("clk4x_rd_strb", self.clk4x_rd_strb),
+                       Instance.Output("norflash_rst_n", pads.norflash_rst_n),
+                       Instance.Output("ddr_clk_pad_p", pads.ddr_clk_p),
+                       Instance.Output("ddr_clk_pad_n", pads.ddr_clk_n),
+                       Instance.Output("eth_phy_clk_pad", pads.eth_phy_clk))
diff --git a/misoclib/norflash/__init__.py b/misoclib/norflash/__init__.py
new file mode 100644 (file)
index 0000000..241d6ac
--- /dev/null
@@ -0,0 +1,24 @@
+from migen.fhdl.std import *
+from migen.bus import wishbone
+from migen.genlib.misc import timeline
+
+class NorFlash(Module):
+       def __init__(self, pads, rd_timing):
+               self.bus = wishbone.Interface()
+       
+               ###
+
+               adr_width = flen(pads.adr) + 1
+               self.comb += [pads.oe_n.eq(0), pads.we_n.eq(1),
+                       pads.ce_n.eq(0)]
+               self.sync += timeline(self.bus.cyc & self.bus.stb, [
+                       (0, [pads.adr.eq(Cat(0, self.bus.adr[:adr_width-2]))]),
+                       (rd_timing, [
+                               self.bus.dat_r[16:].eq(pads.d),
+                               pads.adr.eq(Cat(1, self.bus.adr[:adr_width-2]))]),
+                       (2*rd_timing, [
+                               self.bus.dat_r[:16].eq(pads.d),
+                               self.bus.ack.eq(1)]),
+                       (2*rd_timing + 1, [
+                               self.bus.ack.eq(0)])
+               ])
diff --git a/misoclib/s6ddrphy/__init__.py b/misoclib/s6ddrphy/__init__.py
new file mode 100644 (file)
index 0000000..cb0aa33
--- /dev/null
@@ -0,0 +1,388 @@
+# 1:2 frequency-ratio DDR / LPDDR / DDR2 PHY for 
+# Spartan-6
+# 
+# Assert dfi_wrdata_en and present the data 
+# on dfi_wrdata_mask/dfi_wrdata in the same
+# cycle as the write command.
+#
+# Assert dfi_rddata_en in the same cycle as the read
+# command. The data will come back on dfi_rddata
+# 5 cycles later, along with the assertion 
+# of dfi_rddata_valid.
+#
+# This PHY only supports CAS Latency 3.
+# Read commands must be sent on phase 0.
+# Write commands must be sent on phase 1.
+#
+
+# Todo:
+#      - use CSR for bitslip?
+#      - add configurable CAS Latency
+#      - automatically determines wrphase / rdphase / latencies
+
+from migen.fhdl.std import *
+from migen.bus.dfi import *
+from migen.genlib.record import *
+
+from misoclib import lasmicon
+
+class S6DDRPHY(Module):
+       def __init__(self, pads, memtype, nphases, cl, rd_bitslip, wr_bitslip, dqs_ddr_alignment):
+               if memtype not in ["DDR", "LPDDR", "DDR2"]:
+                       raise NotImplementedError("S6DDRPHY only supports DDR, LPDDR and DDR2")
+               if cl != 3:
+                       raise NotImplementedError("S6DDRPHY only supports CAS LATENCY 3")
+               a = flen(pads.a)
+               ba = flen(pads.ba)
+               d = flen(pads.dq)
+
+               self.phy_settings = lasmicon.PhySettings(
+                       memtype=memtype,
+                       dfi_d=2*d,
+                       nphases=nphases,
+                       rdphase=0,
+                       wrphase=1,
+                       rdcmdphase=1,
+                       wrcmdphase=0,
+                       cl=cl,
+                       read_latency=5,
+                       write_latency=0
+               )
+
+               self.dfi = Interface(a, ba, nphases*d, nphases)
+               self.clk4x_wr_strb = Signal()
+               self.clk4x_rd_strb = Signal()
+
+               ###
+
+               # sys_clk           : system clk, used for dfi interface
+               # sdram_half_clk    : half rate sdram clk 
+               # sdram_full_wr_clk : full rate sdram write clk
+               # sdram_full_rd_clk : full rate sdram write clk
+               sd_sys = getattr(self.sync, "sys")
+               sd_sdram_half = getattr(self.sync, "sdram_half")
+
+               sys_clk = ClockSignal("sys")
+               sdram_half_clk = ClockSignal("sdram_half")
+               sdram_full_wr_clk = ClockSignal("sdram_full_wr")
+               sdram_full_rd_clk = ClockSignal("sdram_full_rd")
+
+               # 
+               # Command/address
+               #
+
+               # select active phase
+               #             sys_clk   ----____----____
+               #  phase_sel(nphases=1) 0       0
+               #  phase_sel(nphases=2) 0   1   0   1
+               #  phase_sel(nphases=4) 0 1 2 3 0 1 2 3
+               phase_sel = Signal(log2_int(nphases))
+               sys_clk_d = Signal()
+
+               sd_sdram_half += [
+                       If(sys_clk & ~sys_clk_d, phase_sel.eq(0)
+                       ).Else(phase_sel.eq(phase_sel+1)),
+                       sys_clk_d.eq(sys_clk)
+               ]
+
+               # register dfi cmds on half_rate clk
+               r_dfi = Array(Record(phase_cmd_description(a, ba)) for i in range(nphases))
+               for n, phase in enumerate(self.dfi.phases):
+                       sd_sdram_half +=[
+                               r_dfi[n].address.eq(phase.address),
+                               r_dfi[n].bank.eq(phase.bank),
+                               r_dfi[n].cs_n.eq(phase.cs_n),
+                               r_dfi[n].cke.eq(phase.cke),
+                               r_dfi[n].cas_n.eq(phase.cas_n),
+                               r_dfi[n].ras_n.eq(phase.ras_n),
+                               r_dfi[n].we_n.eq(phase.we_n)
+                       ]
+
+               # output cmds
+               sd_sdram_half += [
+                       pads.a.eq(r_dfi[phase_sel].address),
+                       pads.ba.eq(r_dfi[phase_sel].bank),
+                       pads.cke.eq(r_dfi[phase_sel].cke),
+                       pads.ras_n.eq(r_dfi[phase_sel].ras_n),
+                       pads.cas_n.eq(r_dfi[phase_sel].cas_n),
+                       pads.we_n.eq(r_dfi[phase_sel].we_n)
+               ]
+               if hasattr(pads, "cs_n"):
+                       sd_sdram_half += pads.cs_n.eq(r_dfi[phase_sel].cs_n)
+
+               # 
+               # Bitslip
+               #
+               bitslip_cnt = Signal(4)
+               bitslip_inc = Signal()
+
+               sd_sys += [
+                       If(bitslip_cnt == rd_bitslip,
+                               bitslip_inc.eq(0)
+                       ).Else(
+                               bitslip_cnt.eq(bitslip_cnt+1),
+                               bitslip_inc.eq(1)
+                       )
+               ]
+
+               # 
+               # DQ/DQS/DM data
+               #
+               sdram_half_clk_n = Signal()
+               self.comb += sdram_half_clk_n.eq(~sdram_half_clk)
+
+               postamble = Signal()
+               drive_dqs = Signal()
+               dqs_t_d0 = Signal()
+               dqs_t_d1 = Signal()
+
+               dqs_o = Signal(d//8) 
+               dqs_t = Signal(d//8)
+
+               self.comb += [
+                       dqs_t_d0.eq(~(drive_dqs | postamble)),
+                       dqs_t_d1.eq(~drive_dqs),
+               ]
+
+               for i in range(d//8):
+                       # DQS output
+                       self.specials += Instance("ODDR2",
+                               Instance.Parameter("DDR_ALIGNMENT", dqs_ddr_alignment),
+                               Instance.Parameter("INIT", 0),
+                               Instance.Parameter("SRTYPE", "ASYNC"),
+
+                               Instance.Input("C0", sdram_half_clk),
+                               Instance.Input("C1", sdram_half_clk_n),
+
+                               Instance.Input("CE", 1),
+                               Instance.Input("D0", 0),
+                               Instance.Input("D1", 1),
+                               Instance.Input("R", 0),
+                               Instance.Input("S", 0),
+
+                               Instance.Output("Q", dqs_o[i])
+                       )
+
+                       # DQS tristate cmd
+                       self.specials += Instance("ODDR2",
+                               Instance.Parameter("DDR_ALIGNMENT", dqs_ddr_alignment),
+                               Instance.Parameter("INIT", 0),
+                               Instance.Parameter("SRTYPE", "ASYNC"),
+
+                               Instance.Input("C0", sdram_half_clk),
+                               Instance.Input("C1", sdram_half_clk_n),
+
+                               Instance.Input("CE", 1),
+                               Instance.Input("D0", dqs_t_d0),
+                               Instance.Input("D1", dqs_t_d1),
+                               Instance.Input("R", 0),
+                               Instance.Input("S", 0),
+
+                               Instance.Output("Q", dqs_t[i])
+                       )
+
+                       # DQS tristate buffer
+                       if hasattr(pads, "dqs_n"):
+                               self.specials += Instance("OBUFTDS",
+                                       Instance.Input("I", dqs_o[i]),
+                                       Instance.Input("T", dqs_t[i]),
+
+                                       Instance.Output("O", pads.dqs[i]),
+                                       Instance.Output("OB", pads.dqs_n[i]),
+                               )
+                       else:
+                               self.specials += Instance("OBUFT",
+                                       Instance.Input("I", dqs_o[i]),
+                                       Instance.Input("T", dqs_t[i]),
+
+                                       Instance.Output("O", pads.dqs[i])
+                               )
+
+               sd_sdram_half += postamble.eq(drive_dqs)
+
+               d_dfi = [Record(phase_wrdata_description(nphases*d)+phase_rddata_description(nphases*d)) 
+                       for i in range(2*nphases)]
+
+               for n, phase in enumerate(self.dfi.phases):
+                       self.comb += [
+                               d_dfi[n].wrdata.eq(phase.wrdata),
+                               d_dfi[n].wrdata_mask.eq(phase.wrdata_mask),
+                               d_dfi[n].wrdata_en.eq(phase.wrdata_en),
+                               d_dfi[n].rddata_en.eq(phase.rddata_en),
+                       ]
+                       sd_sys += [
+                               d_dfi[nphases+n].wrdata.eq(phase.wrdata),
+                               d_dfi[nphases+n].wrdata_mask.eq(phase.wrdata_mask)
+                       ]
+
+
+               drive_dq = Signal()
+               drive_dq_n = [Signal() for i in range(2)]
+               self.comb += drive_dq_n[0].eq(~drive_dq)
+               sd_sys += drive_dq_n[1].eq(drive_dq_n[0])
+
+               dq_t = Signal(d)
+               dq_o = Signal(d)
+               dq_i = Signal(d)
+
+               dq_wrdata = []
+               for i in range(2):
+                       for j in reversed(range(nphases)):
+                               dq_wrdata.append(d_dfi[i*nphases+j].wrdata[:d])
+                               dq_wrdata.append(d_dfi[i*nphases+j].wrdata[d:])
+
+               for i in range(d):
+                       # Data serializer
+                       self.specials += Instance("OSERDES2",
+                               Instance.Parameter("DATA_WIDTH", 4),
+                               Instance.Parameter("DATA_RATE_OQ", "SDR"),
+                               Instance.Parameter("DATA_RATE_OT", "SDR"),
+                               Instance.Parameter("SERDES_MODE", "NONE"),
+                               Instance.Parameter("OUTPUT_MODE", "SINGLE_ENDED"),
+
+                               Instance.Output("OQ", dq_o[i]),
+                               Instance.Input("OCE", 1),
+                               Instance.Input("CLK0", sdram_full_wr_clk),
+                               Instance.Input("CLK1", 0),
+                               Instance.Input("IOCE", self.clk4x_wr_strb),
+                               Instance.Input("RST", 0),
+                               Instance.Input("CLKDIV", sys_clk),
+
+                               Instance.Input("D1", dq_wrdata[wr_bitslip+3][i]),
+                               Instance.Input("D2", dq_wrdata[wr_bitslip+2][i]),
+                               Instance.Input("D3", dq_wrdata[wr_bitslip+1][i]),
+                               Instance.Input("D4", dq_wrdata[wr_bitslip+0][i]),
+
+                               Instance.Output("TQ", dq_t[i]),
+                               Instance.Input("T1", drive_dq_n[(wr_bitslip+3)//4]),
+                               Instance.Input("T2", drive_dq_n[(wr_bitslip+2)//4]),
+                               Instance.Input("T3", drive_dq_n[(wr_bitslip+1)//4]),
+                               Instance.Input("T4", drive_dq_n[(wr_bitslip+0)//4]),
+                               Instance.Input("TRAIN", 0),
+                               Instance.Input("TCE", 1),
+                               Instance.Input("SHIFTIN1", 0),
+                               Instance.Input("SHIFTIN2", 0),
+                               Instance.Input("SHIFTIN3", 0),
+                               Instance.Input("SHIFTIN4", 0),
+
+                               Instance.Output("SHIFTOUT1"),
+                               Instance.Output("SHIFTOUT2"),
+                               Instance.Output("SHIFTOUT3"),
+                               Instance.Output("SHIFTOUT4"),
+                       )
+
+                       # Data deserializer
+                       self.specials += Instance("ISERDES2",
+                               Instance.Parameter("DATA_WIDTH", 4),
+                               Instance.Parameter("DATA_RATE", "SDR"),
+                               Instance.Parameter("BITSLIP_ENABLE", "TRUE"),
+                               Instance.Parameter("SERDES_MODE", "NONE"),
+                               Instance.Parameter("INTERFACE_TYPE", "RETIMED"),
+
+                               Instance.Input("D", dq_i[i]),
+                               Instance.Input("CE0", 1),
+                               Instance.Input("CLK0", sdram_full_rd_clk),
+                               Instance.Input("CLK1", 0),
+                               Instance.Input("IOCE", self.clk4x_rd_strb),
+                               Instance.Input("RST", ResetSignal()),
+                               Instance.Input("CLKDIV", sys_clk),
+                               Instance.Output("SHIFTIN"),
+                               Instance.Input("BITSLIP", bitslip_inc),
+                               Instance.Output("FABRICOUT"),
+
+                               Instance.Output("Q1", d_dfi[0*nphases+0].rddata[i+d]),
+                               Instance.Output("Q2", d_dfi[0*nphases+0].rddata[i]),
+                               Instance.Output("Q3", d_dfi[0*nphases+1].rddata[i+d]),
+                               Instance.Output("Q4", d_dfi[0*nphases+1].rddata[i]),
+
+                               Instance.Output("DFB"),
+                               Instance.Output("CFB0"),
+                               Instance.Output("CFB1"),
+                               Instance.Output("VALID"),
+                               Instance.Output("INCDEC"),
+                               Instance.Output("SHIFTOUT")
+                       )
+
+                       # Data buffer
+                       self.specials += Instance("IOBUF",
+                               Instance.Input("I", dq_o[i]),
+                               Instance.Output("O", dq_i[i]),
+                               Instance.Input("T", dq_t[i]),
+                               Instance.InOut("IO", pads.dq[i])
+                       )
+
+               dq_wrdata_mask = []
+               for i in range(2):
+                       for j in reversed(range(nphases)):
+                               dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[:d//8])
+                               dq_wrdata_mask.append(d_dfi[i*nphases+j].wrdata_mask[d//8:])
+
+               for i in range(d//8):
+                       # Mask serializer
+                       self.specials += Instance("OSERDES2",
+                               Instance.Parameter("DATA_WIDTH", 4),
+                               Instance.Parameter("DATA_RATE_OQ", "SDR"),
+                               Instance.Parameter("DATA_RATE_OT", "SDR"),
+                               Instance.Parameter("SERDES_MODE", "NONE"),
+                               Instance.Parameter("OUTPUT_MODE", "SINGLE_ENDED"),
+
+                               Instance.Output("OQ", pads.dm[i]),
+                               Instance.Input("OCE", 1),
+                               Instance.Input("CLK0", sdram_full_wr_clk),
+                               Instance.Input("CLK1", 0),
+                               Instance.Input("IOCE", self.clk4x_wr_strb),
+                               Instance.Input("RST", 0),
+                               Instance.Input("CLKDIV", sys_clk),
+
+                               Instance.Input("D1", dq_wrdata_mask[wr_bitslip+3][i]),
+                               Instance.Input("D2", dq_wrdata_mask[wr_bitslip+2][i]),
+                               Instance.Input("D3", dq_wrdata_mask[wr_bitslip+1][i]),
+                               Instance.Input("D4", dq_wrdata_mask[wr_bitslip+0][i]),
+
+                               Instance.Output("TQ"),
+                               Instance.Input("T1"),
+                               Instance.Input("T2"),
+                               Instance.Input("T3"),
+                               Instance.Input("T4"),
+                               Instance.Input("TRAIN", 0),
+                               Instance.Input("TCE", 0),
+                               Instance.Input("SHIFTIN1", 0),
+                               Instance.Input("SHIFTIN2", 0),
+                               Instance.Input("SHIFTIN3", 0),
+                               Instance.Input("SHIFTIN4", 0),
+
+                               Instance.Output("SHIFTOUT1"),
+                               Instance.Output("SHIFTOUT2"),
+                               Instance.Output("SHIFTOUT3"),
+                               Instance.Output("SHIFTOUT4"),
+                       )
+
+               #
+               # ODT
+               #
+               # ODT not yet supported
+               if hasattr(pads, "odt"):
+                       self.comb += pads.odt.eq(0)
+
+               # 
+               # DQ/DQS/DM control
+               #
+               self.comb += drive_dq.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
+
+               d_dfi_wrdata_en = Signal()
+               sd_sys += d_dfi_wrdata_en.eq(d_dfi[self.phy_settings.wrphase].wrdata_en)
+               
+               r_dfi_wrdata_en = Signal(2)
+               sd_sdram_half += r_dfi_wrdata_en.eq(Cat(d_dfi_wrdata_en, r_dfi_wrdata_en[0])) 
+
+               self.comb += drive_dqs.eq(r_dfi_wrdata_en[1])
+
+               rddata_sr = Signal(self.phy_settings.read_latency)
+               sd_sys += rddata_sr.eq(Cat(rddata_sr[1:self.phy_settings.read_latency],
+                       d_dfi[self.phy_settings.rdphase].rddata_en))
+               
+               for n, phase in enumerate(self.dfi.phases):
+                       self.comb += [
+                               phase.rddata.eq(d_dfi[n].rddata),
+                               phase.rddata_valid.eq(rddata_sr[0]),
+                       ]
diff --git a/misoclib/s6ddrphy/initsequence.py b/misoclib/s6ddrphy/initsequence.py
new file mode 100644 (file)
index 0000000..3c4c65b
--- /dev/null
@@ -0,0 +1,146 @@
+from migen.fhdl.std import log2_int
+
+def get_sdram_phy_header(sdram_phy):
+       if sdram_phy.phy_settings.memtype not in ["SDR", "DDR", "LPDDR", "DDR2"]:
+               raise NotImplementedError("The SDRAM PHY header generator only supports SDR, DDR, LPDDR and DDR2")
+
+       r = "#ifndef __HW_SDRAM_PHY_H\n#define __HW_SDRAM_PHY_H\n"
+       r += "#include <hw/common.h>\n#include <hw/csr.h>\n#include <hw/flags.h>\n\n"
+
+       r += "static void cdelay(int i);\n"
+
+       #
+       # commands_px functions
+       # 
+       for n in range(sdram_phy.phy_settings.nphases):
+               r += """
+static void command_p{n}(int cmd)
+{{
+       dfii_pi{n}_command_write(cmd);
+       dfii_pi{n}_command_issue_write(1);
+}}""".format(n=str(n))
+       r += "\n\n"
+
+       #
+       # rd/wr access macros
+       #
+       r += """
+#define dfii_pird_address_write(X) dfii_pi{rdphase}_address_write(X)
+#define dfii_piwr_address_write(X) dfii_pi{wrphase}_address_write(X)
+
+#define dfii_pird_baddress_write(X) dfii_pi{rdphase}_baddress_write(X)
+#define dfii_piwr_baddress_write(X) dfii_pi{wrphase}_baddress_write(X)
+
+#define command_prd(X) command_p{rdphase}(X)
+#define command_pwr(X) command_p{wrphase}(X)
+""".format(rdphase=str(sdram_phy.phy_settings.rdphase), wrphase=str(sdram_phy.phy_settings.wrphase)) 
+       r +="\n"
+       
+       #
+       # init sequence
+       # 
+       cmds = {
+               "PRECHARGE_ALL" : "DFII_COMMAND_RAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
+               "MODE_REGISTER" : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_WE|DFII_COMMAND_CS",
+               "AUTO_REFRESH"  : "DFII_COMMAND_RAS|DFII_COMMAND_CAS|DFII_COMMAND_CS",
+               "CKE"           : "DFII_CONTROL_CKE"
+       }
+
+       def gen_cmd(comment, a, ba, cmd, delay):        
+               r = "\t/* {0} */\n".format(comment)
+               r += "\tdfii_pi0_address_write({0:#x});\n".format(a)
+               r += "\tdfii_pi0_baddress_write({0:d});\n".format(ba)
+               if "CKE" in cmd:
+                       r += "\tdfii_control_write({0});\n".format(cmd)
+               else:
+                       r += "\tcommand_p0({0});\n".format(cmd)
+               r += "\tcdelay({0:d});\n".format(delay)
+               r += "\n"
+               return r
+
+
+       r += "static void init_sequence(void)\n{\n"
+
+       cl = sdram_phy.phy_settings.cl
+       
+       if sdram_phy.phy_settings.memtype == "SDR":
+               bl = 1*sdram_phy.phy_settings.nphases
+               mr  = log2_int(bl) + (cl << 4)
+               reset_dll = 1 << 8
+
+               init_sequence = [
+                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
+                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
+               ]
+
+       elif sdram_phy.phy_settings.memtype == "DDR":
+               bl = 2*sdram_phy.phy_settings.nphases
+               mr  = log2_int(bl) + (cl << 4)
+               emr = 0
+               reset_dll = 1 << 8
+
+               init_sequence = [
+                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
+                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
+                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
+               ]
+
+       elif sdram_phy.phy_settings.memtype == "LPDDR":
+               bl = 2*sdram_phy.phy_settings.nphases
+               mr  = log2_int(bl) + (cl << 4)
+               emr = 0
+               reset_dll = 1 << 8
+
+               init_sequence = [
+                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
+                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Load Extended Mode Register", emr, 2, cmds["MODE_REGISTER"], 0),
+                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200)
+               ]
+
+       elif sdram_phy.phy_settings.memtype == "DDR2":
+               bl = 2*sdram_phy.phy_settings.nphases
+               wr = 2
+               mr  = log2_int(bl) + (cl << 4) + (wr << 9)
+               emr = 0
+               emr2 = 0
+               emr3 = 0
+               reset_dll = 1 << 8
+               ocd = 7 << 7
+
+               init_sequence = [
+                       ("Bring CKE high", 0x0000, 0, cmds["CKE"], 2000),
+                       ("Precharge All",  0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Load Extended Mode Register 3", emr3, 3, cmds["MODE_REGISTER"], 0),
+                       ("Load Extended Mode Register 2", emr2, 2, cmds["MODE_REGISTER"], 0),
+                       ("Load Extended Mode Register", emr, 1, cmds["MODE_REGISTER"], 0),
+                       ("Load Mode Register / Reset DLL, CL={0:d}, BL={1:d}".format(cl, bl), mr + reset_dll, 0, cmds["MODE_REGISTER"], 200),
+                       ("Precharge All", 0x0400, 0, cmds["PRECHARGE_ALL"], 0),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Auto Refresh", 0x0, 0, cmds["AUTO_REFRESH"], 4),
+                       ("Load Mode Register / CL={0:d}, BL={1:d}".format(cl, bl), mr, 0, cmds["MODE_REGISTER"], 200),
+                       ("Load Extended Mode Register / OCD Default", emr+ocd, 1, cmds["MODE_REGISTER"], 0),
+                       ("Load Extended Mode Register / OCD Exit", emr, 1, cmds["MODE_REGISTER"], 0),
+               ]
+
+       for comment, a, ba, cmd, delay in init_sequence:
+               r += gen_cmd(comment, a, ba, cmd, delay)
+
+       r += "}\n"
+       r += "#endif\n"
+
+       return r
diff --git a/misoclib/timer/__init__.py b/misoclib/timer/__init__.py
new file mode 100644 (file)
index 0000000..3d1ab70
--- /dev/null
@@ -0,0 +1,33 @@
+from migen.fhdl.std import *
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+
+class Timer(Module, AutoCSR):
+       def __init__(self, width=32):
+               self._load = CSRStorage(width)
+               self._reload = CSRStorage(width)
+               self._en = CSRStorage()
+               self._update_value = CSR()
+               self._value = CSRStatus(width)
+               
+               self.submodules.ev = EventManager()
+               self.ev.zero = EventSourceProcess()
+               self.ev.finalize()
+
+               ###
+
+               value = Signal(width)
+               self.sync += [
+                       If(self._en.storage,
+                               If(value == 0,
+                                       # set reload to 0 to disable reloading
+                                       value.eq(self._reload.storage)
+                               ).Else(
+                                       value.eq(value - 1)
+                               )
+                       ).Else(
+                               value.eq(self._load.storage)
+                       ),
+                       If(self._update_value.re, self._value.status.eq(value))
+               ]
+               self.comb += self.ev.zero.trigger.eq(value != 0)
diff --git a/misoclib/uart/__init__.py b/misoclib/uart/__init__.py
new file mode 100644 (file)
index 0000000..25530d6
--- /dev/null
@@ -0,0 +1,99 @@
+from migen.fhdl.std import *
+from migen.genlib.cdc import MultiReg
+from migen.bank.description import *
+from migen.bank.eventmanager import *
+
+class UART(Module, AutoCSR):
+       def __init__(self, pads, clk_freq, baud=115200):
+               self._rxtx = CSR(8)
+               self._divisor = CSRStorage(16, reset=int(clk_freq/baud/16))
+               
+               self.submodules.ev = EventManager()
+               self.ev.tx = EventSourceProcess()
+               self.ev.rx = EventSourcePulse()
+               self.ev.finalize()
+       
+               ###
+
+               pads.tx.reset = 1
+
+               enable16 = Signal()
+               enable16_counter = Signal(16)
+               self.comb += enable16.eq(enable16_counter == 0)
+               self.sync += [
+                       enable16_counter.eq(enable16_counter - 1),
+                       If(enable16,
+                               enable16_counter.eq(self._divisor.storage - 1))
+               ]
+               
+               # TX
+               tx_reg = Signal(8)
+               tx_bitcount = Signal(4)
+               tx_count16 = Signal(4)
+               tx_busy = self.ev.tx.trigger
+               self.sync += [
+                       If(self._rxtx.re,
+                               tx_reg.eq(self._rxtx.r),
+                               tx_bitcount.eq(0),
+                               tx_count16.eq(1),
+                               tx_busy.eq(1),
+                               pads.tx.eq(0)
+                       ).Elif(enable16 & tx_busy,
+                               tx_count16.eq(tx_count16 + 1),
+                               If(tx_count16 == 0,
+                                       tx_bitcount.eq(tx_bitcount + 1),
+                                       If(tx_bitcount == 8,
+                                               pads.tx.eq(1)
+                                       ).Elif(tx_bitcount == 9,
+                                               pads.tx.eq(1),
+                                               tx_busy.eq(0)
+                                       ).Else(
+                                               pads.tx.eq(tx_reg[0]),
+                                               tx_reg.eq(Cat(tx_reg[1:], 0))
+                                       )
+                               )
+                       )
+               ]
+               
+               # RX
+               rx = Signal()
+               self.specials += MultiReg(pads.rx, rx)
+               rx_r = Signal()
+               rx_reg = Signal(8)
+               rx_bitcount = Signal(4)
+               rx_count16 = Signal(4)
+               rx_busy = Signal()
+               rx_done = self.ev.rx.trigger
+               rx_data = self._rxtx.w
+               self.sync += [
+                       rx_done.eq(0),
+                       If(enable16,
+                               rx_r.eq(rx),
+                               If(~rx_busy,
+                                       If(~rx & rx_r, # look for start bit
+                                               rx_busy.eq(1),
+                                               rx_count16.eq(7),
+                                               rx_bitcount.eq(0)
+                                       )
+                               ).Else(
+                                       rx_count16.eq(rx_count16 + 1),
+                                       If(rx_count16 == 0,
+                                               rx_bitcount.eq(rx_bitcount + 1),
+
+                                               If(rx_bitcount == 0,
+                                                       If(rx, # verify start bit
+                                                               rx_busy.eq(0)
+                                                       )
+                                               ).Elif(rx_bitcount == 9,
+                                                       rx_busy.eq(0),
+                                                       If(rx, # verify stop bit
+                                                               rx_data.eq(rx_reg),
+                                                               rx_done.eq(1)
+                                                       )
+                                               ).Else(
+                                                       rx_reg.eq(Cat(rx_reg[1:], rx))
+                                               )
+                                       )
+                               )
+                       )
+               ]
index 9a7ef979548a74f43a5ab095a44438fbf59d4a29..f6d45b87a719e767759eb3d63fbe2c92121a1af2 100644 (file)
@@ -1,5 +1,5 @@
-M2DIR=../..
-include $(M2DIR)/software/common.mak
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
 
 OBJECTS=isr.o sdram.o main.o boot-helper.o boot.o dataflow.o
 
@@ -9,20 +9,20 @@ all: bios.bin
 -include $(OBJECTS:.o=.d)
 
 %.bin: %.elf
-       $(MAKE) -C $(M2DIR)/tools
+       $(MAKE) -C $(MSCDIR)/tools
        $(OBJCOPY) -O binary $< $@
        chmod -x $@
-       $(M2DIR)/tools/mkmmimg $@ write
+       $(MSCDIR)/tools/mkmscimg $@ write
 
 bios.elf: linker.ld $(OBJECTS) libs
 
 %.elf:
        $(LD) $(LDFLAGS) -T $< -N -o $@ \
-               $(M2DIR)/software/libbase/crt0.o \
+               $(MSCDIR)/software/libbase/crt0.o \
                $(OBJECTS) \
-               -L$(M2DIR)/software/libnet \
-               -L$(M2DIR)/software/libbase \
-               -L$(M2DIR)/software/libcompiler-rt \
+               -L$(MSCDIR)/software/libnet \
+               -L$(MSCDIR)/software/libbase \
+               -L$(MSCDIR)/software/libcompiler-rt \
                -lnet -lbase-nofloat -lcompiler-rt
        chmod -x $@
 
@@ -36,9 +36,9 @@ main.o: main.c
        $(assemble)
 
 libs:
-       $(MAKE) -C $(M2DIR)/software/libcompiler-rt
-       $(MAKE) -C $(M2DIR)/software/libbase
-       $(MAKE) -C $(M2DIR)/software/libnet
+       $(MAKE) -C $(MSCDIR)/software/libcompiler-rt
+       $(MAKE) -C $(MSCDIR)/software/libbase
+       $(MAKE) -C $(MSCDIR)/software/libnet
 
 flash: bios.bin
        m1nor-ng bios.bin
index c3e9a9a49284e0c19f3dcc958174c0d2c6acc5fc..50f4897e866b38322b1f9badf12dcecaa5fa6029 100644 (file)
@@ -307,7 +307,7 @@ static void dfs(char *baseaddr)
 
 static void help(void)
 {
-       puts("Milkymist(tm) BIOS");
+       puts("MiSoC BIOS");
        puts("Don't know what to do? Try 'flashboot'.\n");
        puts("Available commands:");
        puts("mr         - read address space");
@@ -402,7 +402,7 @@ static void crcbios(void)
 }
 
 static const char banner[] =
-       "\nMILKYMIST(tm) v"VERSION" BIOS   http://www.milkymist.org\n"
+       "\nMiSoC(tm) v"VERSION" BIOS   http://www.milkymist.org\n"
        "(c) Copyright 2007-2013 Sebastien Bourdeauducq\n"
        "Built "__DATE__" "__TIME__"\n\n"
        "This program is free software: you can redistribute it and/or modify\n"
index adc7c9362ffd78e3e2699c838a36daa19fc99b9e..825a88e51be06004ef9bbd26a1a7908e7fe1e9e1 100644 (file)
@@ -38,7 +38,7 @@ endif
 
 # Toolchain options
 #
-INCLUDES = -I$(M2DIR)/software/include/base -I$(M2DIR)/software/include -I$(M2DIR)/common
+INCLUDES = -I$(MSCDIR)/software/include/base -I$(MSCDIR)/software/include -I$(MSCDIR)/common
 COMMONFLAGS = -O3 -mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled \
        -Wall -fno-builtin -nostdinc $(INCLUDES)
 CFLAGS = $(COMMONFLAGS) -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes
index 790e4eb0c9d34fec2b8d19472e1cf3b5e6903387..da67b4e234e49c883a6147b6d4d7380aa6b5a242 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Milkymist SoC (Software)
+ * MiSoC
  * Copyright (C) 2007, 2008, 2009, 2011 Sebastien Bourdeauducq
  * Copyright (C) Linux kernel developers
  *
index 9a4c22fede63f140c8791c907eaf3a2a635d15e7..4d0716be6b60206a9bd1c08f897c91e39525f9f4 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Milkymist SoC (Software)
+ * MiSoC
  * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
  * Copyright (C) Linus Torvalds and Linux kernel developers
  *
index b9b9a7ab276d29c46bd06c66904f75f8abac3778..f8a90b1afef1eeffa83e1fc0b51da5ef8fe160ee 100644 (file)
@@ -1,5 +1,5 @@
-M2DIR=../..
-include $(M2DIR)/software/common.mak
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
 
 OBJECTS=setjmp.o libc.o errno.o crc16.o crc32.o console.o system.o id.o uart.o time.o qsort.o strtod.o
 
index bbb927dacabd8e0b1c4ee57e761916cab75f4150..03382966e33a92772b15a9c5ac6a4260d9f96c01 100644 (file)
@@ -43,5 +43,5 @@ void id_print(void)
 
        get_soc_version_formatted(soc_version);
        get_sysid_formatted(sysid);
-       printf("Running on Milkymist-ng SoC %s (sysid:%s) at %dMHz\n", soc_version, sysid, identifier_frequency_read()/1000000);
+       printf("Running on MiSoC %s (sysid:%s) at %dMHz\n", soc_version, sysid, identifier_frequency_read()/1000000);
 }
index 876e195dc1b08dfa0ffdf6d22c93b07c47b82910..e45a79dac31f2a18390e201435be03ab0d935248 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Milkymist SoC (Software)
+ * MiSoC
  * Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
  * Copyright (C) Linus Torvalds and Linux kernel developers
  *
index d23f66a7b3aaec4b9e61ed648d77f4b0b2008f6c..2192974dc546d73173c966e6d57e0fa72f006edc 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Milkymist SoC (Software)
+ * MiSoC
  * Copyright (C) 2007, 2008, 2009 Sebastien Bourdeauducq
  * Copyright (C) Linux kernel developers
  *
index 4bc33fe4f9d33e75cfe548a609fb82bdea8dde8b..feeeb69cb2cf088076a49df82ab8ae716897c0b5 100644 (file)
@@ -1,5 +1,5 @@
-M2DIR=../..
-include $(M2DIR)/software/common.mak
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
 
 CFLAGS+=-D_YUGA_LITTLE_ENDIAN=0 -D_YUGA_BIG_ENDIAN=1 -Wno-missing-prototypes
 
index e0f35a138810685f1c03ea570ccfaa29aad19f6b..ad6a0473c5e4aaa120620c09a96722cf6de2e24d 100644 (file)
@@ -1,5 +1,5 @@
-M2DIR=../..
-include $(M2DIR)/software/common.mak
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
 
 OBJECTS=microudp.o tftp.o
 
index 5647d32a969d9e227754eb8f173241352614f9c6..0a06503c6d2a66d03412c8bb3dc774eccdcb21fb 100644 (file)
@@ -1,5 +1,5 @@
-M2DIR=../..
-include $(M2DIR)/software/common.mak
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
 
 OBJECTS=isr.o main.o
 
@@ -16,12 +16,12 @@ memtest.elf: $(OBJECTS) libs
 
 %.elf:
        $(LD) $(LDFLAGS) \
-               -T $(M2DIR)/software/libbase/linker-sdram.ld \
+               -T $(MSCDIR)/software/libbase/linker-sdram.ld \
                -N -o $@ \
-               $(M2DIR)/software/libbase/crt0.o \
+               $(MSCDIR)/software/libbase/crt0.o \
                $(OBJECTS) \
-               -L$(M2DIR)/software/libbase \
-               -L$(M2DIR)/software/libcompiler-rt \
+               -L$(MSCDIR)/software/libbase \
+               -L$(MSCDIR)/software/libcompiler-rt \
                -lbase -lcompiler-rt
        chmod -x $@
 
@@ -35,12 +35,12 @@ main.o: main.c
        $(assemble)
 
 libs:
-       $(MAKE) -C $(M2DIR)/software/libcompiler-rt
-       $(MAKE) -C $(M2DIR)/software/libbase
+       $(MAKE) -C $(MSCDIR)/software/libcompiler-rt
+       $(MAKE) -C $(MSCDIR)/software/libbase
 
 load: memtest.bin
-       $(MAKE) -C $(M2DIR)/tools
-       $(M2DIR)/tools/flterm --port /dev/ttyUSB0 --kernel memtest.bin
+       $(MAKE) -C $(MSCDIR)/tools
+       $(MSCDIR)/tools/flterm --port /dev/ttyUSB0 --kernel memtest.bin
 
 
 clean:
index 9742ac9d794a75eea7d4c2086cce4e896256ad5f..9ec2f7184d53ad5ca73678e2aa72c5805192dcee 100644 (file)
@@ -1,5 +1,5 @@
-M2DIR=../..
-include $(M2DIR)/software/common.mak
+MSCDIR=../..
+include $(MSCDIR)/software/common.mak
 
 OBJECTS=isr.o fb.o dvisampler0.o dvisampler1.o main.o
 
@@ -13,18 +13,18 @@ all: videomixer.bin videomixer.fbi
        chmod -x $@
 
 %.fbi: %.bin
-       $(M2DIR)/tools/mkmmimg $< write $@
+       $(MSCDIR)/tools/mkmscimg $< write $@
 
 videomixer.elf: $(OBJECTS) libs
 
 %.elf:
        $(LD) $(LDFLAGS) \
-               -T $(M2DIR)/software/libbase/linker-sdram.ld \
+               -T $(MSCDIR)/software/libbase/linker-sdram.ld \
                -N -o $@ \
-               $(M2DIR)/software/libbase/crt0.o \
+               $(MSCDIR)/software/libbase/crt0.o \
                $(OBJECTS) \
-               -L$(M2DIR)/software/libbase \
-               -L$(M2DIR)/software/libcompiler-rt \
+               -L$(MSCDIR)/software/libbase \
+               -L$(MSCDIR)/software/libcompiler-rt \
                -lbase -lcompiler-rt
        chmod -x $@
 
@@ -62,12 +62,12 @@ dvisampler0.o: dvisampler0.h
 dvisampler1.o: dvisampler1.h
 
 libs:
-       $(MAKE) -C $(M2DIR)/software/libcompiler-rt
-       $(MAKE) -C $(M2DIR)/software/libbase
+       $(MAKE) -C $(MSCDIR)/software/libcompiler-rt
+       $(MAKE) -C $(MSCDIR)/software/libbase
 
 load: videomixer.bin
-       $(MAKE) -C $(M2DIR)/tools
-       $(M2DIR)/tools/flterm --port /dev/ttyUSB0 --kernel videomixer.bin
+       $(MAKE) -C $(MSCDIR)/tools
+       $(MSCDIR)/tools/flterm --port /dev/ttyUSB0 --kernel videomixer.bin
 
 flash: videomixer.fbi
        m1nor-ng videomixer.fbi
index 9a8fbf779c306f63d453f9755ca0874c690c13ed..4327d2d38408ca56da6f487c2bada72d57680ff2 100644 (file)
@@ -1,7 +1,7 @@
 from migen.fhdl.std import *
 from migen.sim.generic import *
 
-from milkymist.dvisampler.chansync import ChanSync
+from misoclib.dvisampler.chansync import ChanSync
 
 class TB(Module):
        def __init__(self, test_seq_it):
index bddde1be33dd7ce8e52c44d98d33be463913c63c..9d8d1da14eaa3d4874e5bd035e97edb3cc9e2cd3 100644 (file)
@@ -2,7 +2,7 @@ from migen.fhdl.std import *
 from migen.bus import asmibus
 from migen.sim.generic import Simulator
 
-from milkymist.framebuffer import *
+from misoclib.framebuffer import *
 
 def main():
        hub = asmibus.Hub(16, 128)
index 3564183acbd3a047fdf4a85580ddf7ecca6bae07..3a45daee8815027d9d1783eb43f80d6b115c4c26 100644 (file)
@@ -2,7 +2,7 @@ from migen.fhdl.std import *
 from migen.bus.lasmibus import *
 from migen.sim.generic import Simulator, TopLevel
 
-from milkymist.lasmicon.bankmachine import *
+from misoclib.lasmicon.bankmachine import *
 
 from common import sdram_geom, sdram_timing, CommandLogger
 
index d7acd5c1eeb9f8e27772d288c249b8be87064076..74bf579a55828a7f018a8c46aae3ad5b3c8b18c2 100644 (file)
@@ -4,7 +4,7 @@ from math import ceil
 from migen.fhdl.std import *
 from migen.sim.generic import Proxy
 
-from milkymist import lasmicon
+from misoclib import lasmicon
 
 MHz = 1000000
 clk_freq = (83 + Fraction(1, 3))*MHz
index e64ece39c47d3b8141184835ced7e6125ac4ec2d..6915693801e68fbec30b17f22c25e418c1e88c5d 100644 (file)
@@ -2,7 +2,7 @@ from migen.fhdl.std import *
 from migen.bus.lasmibus import *
 from migen.sim.generic import Simulator, TopLevel
 
-from milkymist.lasmicon import *
+from misoclib.lasmicon import *
 
 from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
 
index 054e1b6606192fab83f6e8293129de5ea6985237..c34c8fad487e63ce05d2a9cf4d6da69593b73ddc 100644 (file)
@@ -3,7 +3,7 @@ from migen.bus import lasmibus
 from migen.actorlib import dma_lasmi
 from migen.sim.generic import Simulator, TopLevel, Proxy
 
-from milkymist.lasmicon import *
+from misoclib.lasmicon import *
 
 from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
 
index 4d6e247645489f56055ce1867acc8ceacdb8b838..ad2f429bcf6a3c8f13b593719429f27bd35591b2 100644 (file)
@@ -3,7 +3,7 @@ from migen.bus import wishbone, wishbone2lasmi, lasmibus
 from migen.bus.transactions import *
 from migen.sim.generic import Simulator, TopLevel
 
-from milkymist.lasmicon import *
+from misoclib.lasmicon import *
 
 from common import sdram_phy, sdram_geom, sdram_timing, DFILogger
 
index 72a527a3f58863b7db370cc89ca3971ec7f2cf6f..daa865307629e07ed513338aed39c55f90081ff6 100644 (file)
@@ -3,7 +3,7 @@ from random import Random
 from migen.fhdl.std import *
 from migen.sim.generic import Simulator, TopLevel
 
-from milkymist.lasmicon.refresher import *
+from misoclib.lasmicon.refresher import *
 
 from common import CommandLogger
 
index 216e33d7d79a4644af2933f62cd30406202a2683..85212499fd28cbf88d68e4f4cb9f8e2873b634af 100644 (file)
@@ -1,4 +1,4 @@
-TARGETS=mkmmimg flterm byteswap
+TARGETS=mkmscimg flterm byteswap
 CC=gcc
 RM ?= rm -f
 
@@ -7,7 +7,7 @@ all: $(TARGETS)
 %: %.c
        $(CC) -O2 -Wall -I../common -s -o $@ $<
 
-install: mkmmimg flterm
+install: mkmscimg flterm
        install -d /usr/local/bin
        install -m755 -t /usr/local/bin $^
 
index 8d12b632aa81ace3a54140faf5ad058ef5088336..3e16236b221c409180d75a8aa3e591d356e74a76 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Milkymist SoC
+ * MiSoC
  * Copyright (C) 2007, 2008, 2009, 2010 Sebastien Bourdeauducq
  *
  * This program is free software: you can redistribute it and/or modify
index 604ba5d75dccbd0b48d24c3483a336e785f6a7d8..2a1c71077aeaf99a2d4e0bed1fd776817e73062e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Milkymist SoC
+ * MiSoC
  * Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq
  * Copyright (C) 2011 Michael Walle
  * Copyright (C) 2004 MontaVista Software, Inc
@@ -645,7 +645,7 @@ static const struct option options[] = {
 
 static void print_usage()
 {
-       fprintf(stderr, "Serial boot program for Milkymist SoC - v. 2.3\n");
+       fprintf(stderr, "Serial boot program for MiSoC - v. 2.4\n");
        fprintf(stderr, "Copyright (C) 2007, 2008, 2009, 2010, 2011 Sebastien Bourdeauducq\n");
        fprintf(stderr, "Copyright (C) 2011 Michael Walle\n");
        fprintf(stderr, "Copyright (C) 2004 MontaVista Software, Inc\n\n");
diff --git a/tools/mkmmimg.c b/tools/mkmmimg.c
deleted file mode 100644 (file)
index e3ad730..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-/*
- * CRC32 computation tool and Milkymist image file writer
- * (c) 2009, 2010, 2012 Sebastien Bourdeauducq
- * Released under GNU GPL v3
- * This file is part of Milkymist.
- */
-
-/* crc32.c -- compute the CRC-32 of a data stream
- * Copyright (C) 1995-1998 Mark Adler
- * For conditions of distribution and use, see copyright notice in zlib.h
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/mman.h>
-#include <string.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-const unsigned int crc_table[256] = {
-       0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
-       0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
-       0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
-       0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
-       0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
-       0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
-       0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
-       0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
-       0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
-       0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
-       0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
-       0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
-       0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
-       0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
-       0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
-       0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
-       0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
-       0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
-       0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
-       0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
-       0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
-       0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
-       0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
-       0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
-       0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
-       0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
-       0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
-       0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
-       0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
-       0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
-       0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
-       0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
-       0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
-       0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
-       0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
-       0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
-       0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
-       0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
-       0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
-       0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
-       0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
-       0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
-       0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
-       0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
-       0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
-       0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
-       0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
-       0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
-       0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
-       0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
-       0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
-       0x2d02ef8dL
-};
-
-#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
-#define DO2(buf)  DO1(buf); DO1(buf);
-#define DO4(buf)  DO2(buf); DO2(buf);
-#define DO8(buf)  DO4(buf); DO4(buf);
-
-static unsigned int crc32(const unsigned char *buffer, unsigned int len)
-{
-       unsigned int crc;
-       crc = 0;
-       crc = crc ^ 0xffffffffL;
-       while(len >= 8) {
-               DO8(buffer);
-               len -= 8;
-       }
-       if(len) do {
-               DO1(buffer);
-       } while(--len);
-       return crc ^ 0xffffffffL;
-}
-
-int main(int argc, char *argv[])
-{
-       int fd, fd_out;
-       unsigned char *buffer;
-       unsigned int length;
-       unsigned int crc;
-       
-       if(((argc != 2) && (argc != 3) && (argc != 4))
-               || ((argc > 2) && (strcmp(argv[2], "write")))) {
-               fprintf(stderr, "Usage: mkmmimg <filename> [write] [dest]\n");
-               return 1;
-       }
-       
-       fd = open(argv[1], O_RDONLY);
-       if(fd == -1) {
-               perror("open");
-               return 1;
-       }
-       
-       length = lseek(fd, 0, SEEK_END);
-       lseek(fd, 0, SEEK_SET);
-       
-       buffer = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
-       if(!buffer) {
-               perror("mmap");
-               close(fd);
-               return 1;
-       }
-       crc = crc32(buffer, length);
-       printf("CRC32 (%s): %08x\n", argv[1], crc);
-
-       if(argc == 3) {
-               /* Write the CRC32 in big endian at the end of the file */
-               char b[4];
-
-               fd_out = open(argv[1], O_WRONLY|O_APPEND);
-               if(fd_out == -1) {
-                       perror("open");
-                       return 1;
-               }
-               b[0] = (crc & 0xff000000) >> 24;
-               b[1] = (crc & 0x00ff0000) >> 16;
-               b[2] = (crc & 0x0000ff00) >> 8;
-               b[3] = (crc & 0x000000ff) >> 0;
-               write(fd_out, &b[0], 4);
-               close(fd_out);
-       }
-
-       if(argc == 4) {
-               /* Write a new file prepended with the size and CRC */
-               char b[4];
-
-               fd_out = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
-               if(fd_out == -1) {
-                       perror("open");
-                       return 1;
-               }
-               b[0] = (length & 0xff000000) >> 24;
-               b[1] = (length & 0x00ff0000) >> 16;
-               b[2] = (length & 0x0000ff00) >> 8;
-               b[3] = (length & 0x000000ff) >> 0;
-               write(fd_out, &b[0], 4);
-               b[0] = (crc & 0xff000000) >> 24;
-               b[1] = (crc & 0x00ff0000) >> 16;
-               b[2] = (crc & 0x0000ff00) >> 8;
-               b[3] = (crc & 0x000000ff) >> 0;
-               write(fd_out, &b[0], 4);
-               write(fd_out, buffer, length);
-               close(fd_out);
-       }
-
-       munmap(buffer, length);
-       close(fd);
-
-       return 0;
-}
diff --git a/tools/mkmscimg.c b/tools/mkmscimg.c
new file mode 100644 (file)
index 0000000..49830fe
--- /dev/null
@@ -0,0 +1,172 @@
+/*
+ * CRC32 computation tool and MiSoC image file writer
+ * (c) 2009, 2010, 2012 Sebastien Bourdeauducq
+ * Released under GNU GPL v3
+ * This file is part of MiSoC.
+ */
+
+/* crc32.c -- compute the CRC-32 of a data stream
+ * Copyright (C) 1995-1998 Mark Adler
+ * For conditions of distribution and use, see copyright notice in zlib.h
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/mman.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+const unsigned int crc_table[256] = {
+       0x00000000L, 0x77073096L, 0xee0e612cL, 0x990951baL, 0x076dc419L,
+       0x706af48fL, 0xe963a535L, 0x9e6495a3L, 0x0edb8832L, 0x79dcb8a4L,
+       0xe0d5e91eL, 0x97d2d988L, 0x09b64c2bL, 0x7eb17cbdL, 0xe7b82d07L,
+       0x90bf1d91L, 0x1db71064L, 0x6ab020f2L, 0xf3b97148L, 0x84be41deL,
+       0x1adad47dL, 0x6ddde4ebL, 0xf4d4b551L, 0x83d385c7L, 0x136c9856L,
+       0x646ba8c0L, 0xfd62f97aL, 0x8a65c9ecL, 0x14015c4fL, 0x63066cd9L,
+       0xfa0f3d63L, 0x8d080df5L, 0x3b6e20c8L, 0x4c69105eL, 0xd56041e4L,
+       0xa2677172L, 0x3c03e4d1L, 0x4b04d447L, 0xd20d85fdL, 0xa50ab56bL,
+       0x35b5a8faL, 0x42b2986cL, 0xdbbbc9d6L, 0xacbcf940L, 0x32d86ce3L,
+       0x45df5c75L, 0xdcd60dcfL, 0xabd13d59L, 0x26d930acL, 0x51de003aL,
+       0xc8d75180L, 0xbfd06116L, 0x21b4f4b5L, 0x56b3c423L, 0xcfba9599L,
+       0xb8bda50fL, 0x2802b89eL, 0x5f058808L, 0xc60cd9b2L, 0xb10be924L,
+       0x2f6f7c87L, 0x58684c11L, 0xc1611dabL, 0xb6662d3dL, 0x76dc4190L,
+       0x01db7106L, 0x98d220bcL, 0xefd5102aL, 0x71b18589L, 0x06b6b51fL,
+       0x9fbfe4a5L, 0xe8b8d433L, 0x7807c9a2L, 0x0f00f934L, 0x9609a88eL,
+       0xe10e9818L, 0x7f6a0dbbL, 0x086d3d2dL, 0x91646c97L, 0xe6635c01L,
+       0x6b6b51f4L, 0x1c6c6162L, 0x856530d8L, 0xf262004eL, 0x6c0695edL,
+       0x1b01a57bL, 0x8208f4c1L, 0xf50fc457L, 0x65b0d9c6L, 0x12b7e950L,
+       0x8bbeb8eaL, 0xfcb9887cL, 0x62dd1ddfL, 0x15da2d49L, 0x8cd37cf3L,
+       0xfbd44c65L, 0x4db26158L, 0x3ab551ceL, 0xa3bc0074L, 0xd4bb30e2L,
+       0x4adfa541L, 0x3dd895d7L, 0xa4d1c46dL, 0xd3d6f4fbL, 0x4369e96aL,
+       0x346ed9fcL, 0xad678846L, 0xda60b8d0L, 0x44042d73L, 0x33031de5L,
+       0xaa0a4c5fL, 0xdd0d7cc9L, 0x5005713cL, 0x270241aaL, 0xbe0b1010L,
+       0xc90c2086L, 0x5768b525L, 0x206f85b3L, 0xb966d409L, 0xce61e49fL,
+       0x5edef90eL, 0x29d9c998L, 0xb0d09822L, 0xc7d7a8b4L, 0x59b33d17L,
+       0x2eb40d81L, 0xb7bd5c3bL, 0xc0ba6cadL, 0xedb88320L, 0x9abfb3b6L,
+       0x03b6e20cL, 0x74b1d29aL, 0xead54739L, 0x9dd277afL, 0x04db2615L,
+       0x73dc1683L, 0xe3630b12L, 0x94643b84L, 0x0d6d6a3eL, 0x7a6a5aa8L,
+       0xe40ecf0bL, 0x9309ff9dL, 0x0a00ae27L, 0x7d079eb1L, 0xf00f9344L,
+       0x8708a3d2L, 0x1e01f268L, 0x6906c2feL, 0xf762575dL, 0x806567cbL,
+       0x196c3671L, 0x6e6b06e7L, 0xfed41b76L, 0x89d32be0L, 0x10da7a5aL,
+       0x67dd4accL, 0xf9b9df6fL, 0x8ebeeff9L, 0x17b7be43L, 0x60b08ed5L,
+       0xd6d6a3e8L, 0xa1d1937eL, 0x38d8c2c4L, 0x4fdff252L, 0xd1bb67f1L,
+       0xa6bc5767L, 0x3fb506ddL, 0x48b2364bL, 0xd80d2bdaL, 0xaf0a1b4cL,
+       0x36034af6L, 0x41047a60L, 0xdf60efc3L, 0xa867df55L, 0x316e8eefL,
+       0x4669be79L, 0xcb61b38cL, 0xbc66831aL, 0x256fd2a0L, 0x5268e236L,
+       0xcc0c7795L, 0xbb0b4703L, 0x220216b9L, 0x5505262fL, 0xc5ba3bbeL,
+       0xb2bd0b28L, 0x2bb45a92L, 0x5cb36a04L, 0xc2d7ffa7L, 0xb5d0cf31L,
+       0x2cd99e8bL, 0x5bdeae1dL, 0x9b64c2b0L, 0xec63f226L, 0x756aa39cL,
+       0x026d930aL, 0x9c0906a9L, 0xeb0e363fL, 0x72076785L, 0x05005713L,
+       0x95bf4a82L, 0xe2b87a14L, 0x7bb12baeL, 0x0cb61b38L, 0x92d28e9bL,
+       0xe5d5be0dL, 0x7cdcefb7L, 0x0bdbdf21L, 0x86d3d2d4L, 0xf1d4e242L,
+       0x68ddb3f8L, 0x1fda836eL, 0x81be16cdL, 0xf6b9265bL, 0x6fb077e1L,
+       0x18b74777L, 0x88085ae6L, 0xff0f6a70L, 0x66063bcaL, 0x11010b5cL,
+       0x8f659effL, 0xf862ae69L, 0x616bffd3L, 0x166ccf45L, 0xa00ae278L,
+       0xd70dd2eeL, 0x4e048354L, 0x3903b3c2L, 0xa7672661L, 0xd06016f7L,
+       0x4969474dL, 0x3e6e77dbL, 0xaed16a4aL, 0xd9d65adcL, 0x40df0b66L,
+       0x37d83bf0L, 0xa9bcae53L, 0xdebb9ec5L, 0x47b2cf7fL, 0x30b5ffe9L,
+       0xbdbdf21cL, 0xcabac28aL, 0x53b39330L, 0x24b4a3a6L, 0xbad03605L,
+       0xcdd70693L, 0x54de5729L, 0x23d967bfL, 0xb3667a2eL, 0xc4614ab8L,
+       0x5d681b02L, 0x2a6f2b94L, 0xb40bbe37L, 0xc30c8ea1L, 0x5a05df1bL,
+       0x2d02ef8dL
+};
+
+#define DO1(buf) crc = crc_table[((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8);
+#define DO2(buf)  DO1(buf); DO1(buf);
+#define DO4(buf)  DO2(buf); DO2(buf);
+#define DO8(buf)  DO4(buf); DO4(buf);
+
+static unsigned int crc32(const unsigned char *buffer, unsigned int len)
+{
+       unsigned int crc;
+       crc = 0;
+       crc = crc ^ 0xffffffffL;
+       while(len >= 8) {
+               DO8(buffer);
+               len -= 8;
+       }
+       if(len) do {
+               DO1(buffer);
+       } while(--len);
+       return crc ^ 0xffffffffL;
+}
+
+int main(int argc, char *argv[])
+{
+       int fd, fd_out;
+       unsigned char *buffer;
+       unsigned int length;
+       unsigned int crc;
+       
+       if(((argc != 2) && (argc != 3) && (argc != 4))
+               || ((argc > 2) && (strcmp(argv[2], "write")))) {
+               fprintf(stderr, "Usage: mkmscimg <filename> [write] [dest]\n");
+               return 1;
+       }
+       
+       fd = open(argv[1], O_RDONLY);
+       if(fd == -1) {
+               perror("open");
+               return 1;
+       }
+       
+       length = lseek(fd, 0, SEEK_END);
+       lseek(fd, 0, SEEK_SET);
+       
+       buffer = mmap(NULL, length, PROT_READ, MAP_SHARED, fd, 0);
+       if(!buffer) {
+               perror("mmap");
+               close(fd);
+               return 1;
+       }
+       crc = crc32(buffer, length);
+       printf("CRC32 (%s): %08x\n", argv[1], crc);
+
+       if(argc == 3) {
+               /* Write the CRC32 in big endian at the end of the file */
+               char b[4];
+
+               fd_out = open(argv[1], O_WRONLY|O_APPEND);
+               if(fd_out == -1) {
+                       perror("open");
+                       return 1;
+               }
+               b[0] = (crc & 0xff000000) >> 24;
+               b[1] = (crc & 0x00ff0000) >> 16;
+               b[2] = (crc & 0x0000ff00) >> 8;
+               b[3] = (crc & 0x000000ff) >> 0;
+               write(fd_out, &b[0], 4);
+               close(fd_out);
+       }
+
+       if(argc == 4) {
+               /* Write a new file prepended with the size and CRC */
+               char b[4];
+
+               fd_out = open(argv[3], O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);
+               if(fd_out == -1) {
+                       perror("open");
+                       return 1;
+               }
+               b[0] = (length & 0xff000000) >> 24;
+               b[1] = (length & 0x00ff0000) >> 16;
+               b[2] = (length & 0x0000ff00) >> 8;
+               b[3] = (length & 0x000000ff) >> 0;
+               write(fd_out, &b[0], 4);
+               b[0] = (crc & 0xff000000) >> 24;
+               b[1] = (crc & 0x00ff0000) >> 16;
+               b[2] = (crc & 0x0000ff00) >> 8;
+               b[3] = (crc & 0x000000ff) >> 0;
+               write(fd_out, &b[0], 4);
+               write(fd_out, buffer, length);
+               close(fd_out);
+       }
+
+       munmap(buffer, length);
+       close(fd);
+
+       return 0;
+}
diff --git a/top.py b/top.py
index d25a95af498563795da4342dfb1508e3d36b2425..67022bef34cf130baa7098b536cb974a2d95dfd4 100644 (file)
--- a/top.py
+++ b/top.py
@@ -8,7 +8,7 @@ from migen.bus import wishbone2lasmi, wishbone2csr
 from migen.bank import csrgen
 from mibuild.generic_platform import ConstraintError
 
-from milkymist import mxcrg, lm32, norflash, uart, s6ddrphy, dfii, lasmicon, \
+from misoclib import mxcrg, lm32, norflash, uart, s6ddrphy, dfii, lasmicon, \
        identifier, timer, minimac3, framebuffer, dvisampler, gpio, memtest
 
 version = "2.0"