From 6a0f85dc423f0c98f483d85f2c4cd57b31270a8b Mon Sep 17 00:00:00 2001 From: Florent Kermarrec Date: Sat, 7 Nov 2015 12:26:46 +0100 Subject: [PATCH] litex: reorganize things, first work working version --- .gitignore | 8 +- .gitmodules | 12 + .travis.yml | 52 -- MANIFEST.in | 3 + README | 42 ++ README.rst | 82 -- conda/migen/bld.bat | 1 - conda/migen/meta.yaml | 28 - doc/Makefile | 130 ---- doc/_build/.keep_me | 0 doc/_static/.keep_me | 0 doc/_templates/.keep_me | 0 doc/conf.py | 223 ------ doc/fhdl.rst | 362 --------- doc/index.rst | 11 - doc/introduction.rst | 73 -- doc/migen_logo.png | Bin 74931 -> 0 bytes doc/migen_logo.svg | 224 ------ doc/reference.rst | 37 - doc/simulation.rst | 6 - doc/synthesis.rst | 4 - examples/basic/arrays.py | 28 - examples/basic/fsm.py | 31 - examples/basic/graycounter.py | 18 - examples/basic/instance.py | 68 -- examples/basic/local_cd.py | 19 - examples/basic/memory.py | 17 - examples/basic/namer.py | 44 -- examples/basic/psync.py | 23 - examples/basic/record.py | 26 - examples/basic/reslice.py | 19 - examples/basic/tristate.py | 13 - examples/basic/two_dividers.py | 19 - examples/sim/basic1.py | 29 - examples/sim/basic2.py | 37 - examples/sim/fir.py | 67 -- examples/sim/memory.py | 26 - litex/{gen/migen/build => }/__init__.py | 0 .../build/platforms => boards}/__init__.py | 0 .../fhdl => boards/platforms}/__init__.py | 0 .../build => boards}/platforms/de0nano.py | 6 +- .../build => litex/boards}/platforms/kc705.py | 6 +- .../boards}/platforms/minispartan6.py | 6 +- .../build => litex/boards}/platforms/sim.py | 4 +- .../build => litex/boards}/platforms/versa.py | 6 +- .../genlib => boards/targets}/__init__.py | 0 .../{soc/misoc => boards}/targets/de0nano.py | 14 +- litex/{soc/misoc => boards}/targets/kc705.py | 24 +- .../misoc => boards}/targets/minispartan6.py | 16 +- .../misoc => boards}/targets/papilio_pro.py | 18 +- .../misoc => boards}/targets/pipistrello.py | 18 +- litex/{soc/misoc => boards}/targets/simple.py | 17 +- litex/{gen/migen/test => build}/__init__.py | 0 litex/build/altera/__init__.py | 2 + litex/{gen/migen => }/build/altera/common.py | 6 +- {migen => litex}/build/altera/platform.py | 4 +- {migen => litex}/build/altera/programmer.py | 2 +- litex/{gen/migen => }/build/altera/quartus.py | 8 +- {migen => litex}/build/generic_platform.py | 10 +- .../migen => }/build/generic_programmer.py | 3 +- litex/build/lattice/__init__.py | 2 + litex/{gen/migen => }/build/lattice/common.py | 8 +- {migen => litex}/build/lattice/diamond.py | 10 +- {migen => litex}/build/lattice/platform.py | 4 +- .../migen => }/build/lattice/programmer.py | 4 +- litex/{gen/migen => }/build/openocd.py | 2 +- litex/build/sim/__init__.py | 1 + litex/{gen/migen => }/build/sim/common.py | 0 litex/{gen/migen => }/build/sim/dut_tb.cpp | 0 litex/{gen/migen => }/build/sim/platform.py | 4 +- litex/{gen/migen => }/build/sim/verilator.py | 8 +- litex/{gen/migen => }/build/tools.py | 0 litex/build/xilinx/__init__.py | 2 + litex/{gen/migen => }/build/xilinx/common.py | 18 +- litex/{gen/migen => }/build/xilinx/ise.py | 12 +- .../{gen/migen => }/build/xilinx/platform.py | 4 +- .../migen => }/build/xilinx/programmer.py | 4 +- {migen => litex}/build/xilinx/vivado.py | 12 +- litex/gen/.gitignore | 7 - litex/gen/.travis.yml | 52 -- litex/gen/LICENSE | 31 - LICENSE => litex/gen/MIGEN_LICENSE | 0 litex/gen/README.rst | 82 -- litex/gen/__init__.py | 10 + litex/gen/conda/migen/bld.bat | 1 - litex/gen/conda/migen/meta.yaml | 28 - litex/gen/doc/Makefile | 130 ---- litex/gen/doc/_static/.keep_me | 0 litex/gen/doc/_templates/.keep_me | 0 litex/gen/doc/conf.py | 223 ------ litex/gen/doc/fhdl.rst | 362 --------- litex/gen/doc/index.rst | 11 - litex/gen/doc/introduction.rst | 73 -- litex/gen/doc/migen_logo.png | Bin 74931 -> 0 bytes litex/gen/doc/migen_logo.svg | 224 ------ litex/gen/doc/reference.rst | 37 - litex/gen/doc/simulation.rst | 6 - litex/gen/doc/synthesis.rst | 4 - litex/gen/examples/basic/arrays.py | 28 - litex/gen/examples/basic/fsm.py | 31 - litex/gen/examples/basic/graycounter.py | 18 - litex/gen/examples/basic/instance.py | 68 -- litex/gen/examples/basic/local_cd.py | 19 - litex/gen/examples/basic/memory.py | 17 - litex/gen/examples/basic/namer.py | 44 -- litex/gen/examples/basic/psync.py | 23 - litex/gen/examples/basic/record.py | 26 - litex/gen/examples/basic/reslice.py | 19 - litex/gen/examples/basic/tristate.py | 13 - litex/gen/examples/basic/two_dividers.py | 19 - litex/gen/examples/sim/basic1.py | 29 - litex/gen/examples/sim/basic2.py | 37 - litex/gen/examples/sim/fir.py | 67 -- litex/gen/examples/sim/memory.py | 26 - litex/gen/{migen/util => fhdl}/__init__.py | 0 {migen => litex/gen}/fhdl/bitcontainer.py | 2 +- litex/gen/{migen => }/fhdl/conv_output.py | 0 litex/gen/{migen => }/fhdl/decorators.py | 6 +- {migen => litex/gen}/fhdl/edif.py | 10 +- {migen => litex/gen}/fhdl/module.py | 8 +- litex/gen/{migen => }/fhdl/namer.py | 4 +- {migen => litex/gen}/fhdl/simplify.py | 8 +- {migen => litex/gen}/fhdl/specials.py | 12 +- {migen => litex/gen}/fhdl/structure.py | 12 +- litex/gen/{migen => }/fhdl/tools.py | 10 +- litex/gen/{migen => }/fhdl/tracer.py | 0 litex/gen/{migen => }/fhdl/verilog.py | 14 +- litex/gen/{migen => }/fhdl/visit.py | 4 +- litex/{soc/misoc => gen/genlib}/__init__.py | 0 {migen => litex/gen}/genlib/cdc.py | 10 +- litex/gen/{migen => }/genlib/coding.py | 4 +- {migen => litex/gen}/genlib/divider.py | 4 +- {migen => litex/gen}/genlib/fifo.py | 12 +- litex/gen/{migen => }/genlib/fsm.py | 10 +- litex/gen/{migen => }/genlib/io.py | 6 +- {migen => litex/gen}/genlib/misc.py | 6 +- litex/gen/{migen => }/genlib/record.py | 4 +- litex/gen/{migen => }/genlib/resetsync.py | 4 +- litex/gen/{migen => }/genlib/roundrobin.py | 4 +- {migen => litex/gen}/genlib/sort.py | 4 +- litex/gen/migen/__init__.py | 10 - litex/gen/migen/build/altera/__init__.py | 2 - litex/gen/migen/build/altera/platform.py | 27 - litex/gen/migen/build/altera/programmer.py | 13 - litex/gen/migen/build/fpgalink_programmer.py | 102 --- litex/gen/migen/build/generic_platform.py | 343 --------- litex/gen/migen/build/lattice/__init__.py | 2 - litex/gen/migen/build/lattice/diamond.py | 105 --- litex/gen/migen/build/lattice/platform.py | 26 - litex/gen/migen/build/platforms/apf27.py | 150 ---- litex/gen/migen/build/platforms/apf51.py | 177 ----- litex/gen/migen/build/platforms/kc705.py | 458 ----------- .../migen/build/platforms/lx9_microboard.py | 131 ---- litex/gen/migen/build/platforms/m1.py | 152 ---- litex/gen/migen/build/platforms/mercury.py | 138 ---- litex/gen/migen/build/platforms/mimasv2.py | 124 --- .../gen/migen/build/platforms/minispartan6.py | 126 ---- litex/gen/migen/build/platforms/mixxeo.py | 188 ----- litex/gen/migen/build/platforms/ml605.py | 60 -- .../gen/migen/build/platforms/papilio_pro.py | 62 -- .../gen/migen/build/platforms/pipistrello.py | 138 ---- litex/gen/migen/build/platforms/rhino.py | 142 ---- litex/gen/migen/build/platforms/roach.py | 35 - litex/gen/migen/build/platforms/sim.py | 45 -- litex/gen/migen/build/platforms/usrp_b100.py | 152 ---- litex/gen/migen/build/platforms/versa.py | 96 --- litex/gen/migen/build/platforms/zedboard.py | 145 ---- litex/gen/migen/build/platforms/ztex_115d.py | 110 --- litex/gen/migen/build/sim/__init__.py | 1 - litex/gen/migen/build/xilinx/__init__.py | 2 - litex/gen/migen/build/xilinx/vivado.py | 138 ---- litex/gen/migen/fhdl/bitcontainer.py | 121 --- litex/gen/migen/fhdl/edif.py | 213 ------ litex/gen/migen/fhdl/module.py | 185 ----- litex/gen/migen/fhdl/simplify.py | 114 --- litex/gen/migen/fhdl/specials.py | 360 --------- litex/gen/migen/fhdl/structure.py | 713 ------------------ litex/gen/migen/genlib/cdc.py | 141 ---- litex/gen/migen/genlib/divider.py | 40 - litex/gen/migen/genlib/fifo.py | 214 ------ litex/gen/migen/genlib/misc.py | 88 --- litex/gen/migen/genlib/sort.py | 71 -- litex/gen/migen/sim/__init__.py | 1 - litex/gen/migen/sim/vcd.py | 75 -- litex/gen/migen/test/support.py | 13 - litex/gen/migen/test/test_coding.py | 113 --- litex/gen/migen/test/test_constant.py | 29 - litex/gen/migen/test/test_divider.py | 28 - litex/gen/migen/test/test_examples.py | 49 -- litex/gen/migen/test/test_fifo.py | 56 -- litex/gen/migen/test/test_signed.py | 42 -- litex/gen/migen/test/test_size.py | 19 - litex/gen/migen/test/test_sort.py | 30 - litex/gen/migen/test/test_syntax.py | 62 -- litex/gen/migen/util/treeviz.py | 112 --- litex/gen/setup.py | 35 - litex/gen/sim/__init__.py | 1 + litex/gen/{migen => }/sim/core.py | 14 +- {migen => litex/gen}/sim/vcd.py | 2 +- litex/gen/tools/strace_tailor.sh | 16 - .../{soc/misoc/cores => gen/util}/__init__.py | 0 litex/gen/{migen => }/util/misc.py | 0 litex/soc/.gitignore | 5 - litex/soc/.gitmodules | 12 - litex/soc/.travis.yml | 36 - litex/soc/CONTRIBUTING.rst | 68 -- litex/soc/MANIFEST.in | 4 - litex/soc/{LICENSE => MISOC_LICENSE} | 0 litex/soc/README | 138 ---- .../cores/liteeth_mini => }/__init__.py | 0 litex/soc/conda/misoc/bld.bat | 1 - litex/soc/conda/misoc/meta.yaml | 26 - .../mac/frontend => cores}/__init__.py | 0 .../interconnect => cores/cpu}/__init__.py | 0 litex/soc/cores/cpu/lm32/__init__.py | 1 + .../{misoc/cores => cores/cpu}/lm32/core.py | 4 +- .../cpu}/lm32/verilog/lm32_config.v | 0 litex/soc/cores/cpu/lm32/verilog/submodule | 1 + litex/soc/cores/cpu/mor1kx/__init__.py | 1 + .../{misoc/cores => cores/cpu}/mor1kx/core.py | 4 +- litex/soc/cores/cpu/mor1kx/verilog | 1 + .../targets => cores/flash}/__init__.py | 0 .../cores => cores/flash}/nor_flash_16.py | 6 +- .../{misoc/cores => cores/flash}/spi_flash.py | 8 +- litex/soc/{misoc => }/cores/gpio.py | 6 +- litex/soc/{misoc => }/cores/identifier.py | 4 +- .../{misoc/tools => cores/sdram}/__init__.py | 0 .../soc/{misoc/cores => cores/sdram}/dfii.py | 4 +- litex/soc/cores/sdram/lasmicon/__init__.py | 1 + .../sdram}/lasmicon/bankmachine.py | 10 +- .../cores => cores/sdram}/lasmicon/core.py | 10 +- .../sdram}/lasmicon/multiplexer.py | 10 +- .../cores => cores/sdram}/lasmicon/perf.py | 4 +- .../sdram}/lasmicon/refresher.py | 8 +- litex/soc/cores/sdram/minicon/__init__.py | 1 + .../cores => cores/sdram}/minicon/core.py | 10 +- .../sdram_model.py => cores/sdram/model.py} | 10 +- litex/soc/cores/sdram/phy/__init__.py | 3 + .../sdram/phy}/gensdrphy.py | 10 +- .../sdram_phy => cores/sdram/phy}/k7ddrphy.py | 8 +- .../sdram_phy => cores/sdram/phy}/s6ddrphy.py | 8 +- .../sdram/settings.py} | 2 +- .../sdram_tester.py => cores/sdram/tester.py} | 10 +- litex/soc/cores/spi/__init__.py | 1 + litex/soc/{misoc => }/cores/spi/core.py | 6 +- litex/soc/{misoc => }/cores/spi/test.py | 8 +- litex/soc/{misoc => }/cores/timer.py | 6 +- litex/soc/cores/uart/__init__.py | 1 + litex/soc/{misoc => }/cores/uart/core.py | 12 +- litex/soc/integration/__init__.py | 2 + litex/soc/{misoc => }/integration/builder.py | 16 +- .../{misoc => }/integration/cpu_interface.py | 4 +- .../soc/{misoc => }/integration/sdram_init.py | 2 +- litex/soc/{misoc => }/integration/soc_core.py | 7 +- .../soc/{misoc => }/integration/soc_sdram.py | 22 +- .../soc/interconnect}/__init__.py | 0 litex/soc/{misoc => }/interconnect/csr.py | 6 +- litex/soc/{misoc => }/interconnect/csr_bus.py | 12 +- .../interconnect/csr_eventmanager.py | 6 +- litex/soc/{misoc => }/interconnect/dfi.py | 4 +- .../soc/{misoc => }/interconnect/dma_lasmi.py | 4 +- .../soc/{misoc => }/interconnect/lasmi_bus.py | 6 +- litex/soc/{misoc => }/interconnect/stream.py | 8 +- .../soc/{misoc => }/interconnect/wishbone.py | 16 +- .../{misoc => }/interconnect/wishbone2csr.py | 6 +- .../interconnect/wishbone2lasmi.py | 4 +- litex/soc/misoc/cores/dvi_sampler/__init__.py | 1 - litex/soc/misoc/cores/dvi_sampler/analysis.py | 207 ----- litex/soc/misoc/cores/dvi_sampler/chansync.py | 134 ---- litex/soc/misoc/cores/dvi_sampler/charsync.py | 56 -- litex/soc/misoc/cores/dvi_sampler/clocking.py | 81 -- litex/soc/misoc/cores/dvi_sampler/common.py | 2 - litex/soc/misoc/cores/dvi_sampler/core.py | 80 -- .../misoc/cores/dvi_sampler/datacapture.py | 188 ----- litex/soc/misoc/cores/dvi_sampler/debug.py | 49 -- litex/soc/misoc/cores/dvi_sampler/decoding.py | 25 - litex/soc/misoc/cores/dvi_sampler/dma.py | 146 ---- litex/soc/misoc/cores/dvi_sampler/edid.py | 196 ----- litex/soc/misoc/cores/dvi_sampler/wer.py | 62 -- litex/soc/misoc/cores/framebuffer/__init__.py | 1 - litex/soc/misoc/cores/framebuffer/core.py | 33 - litex/soc/misoc/cores/framebuffer/dvi.py | 227 ------ litex/soc/misoc/cores/framebuffer/format.py | 150 ---- litex/soc/misoc/cores/framebuffer/phy.py | 222 ------ litex/soc/misoc/cores/lasmicon/__init__.py | 1 - .../misoc/cores/lasmicon/test_bankmachine.py | 43 -- litex/soc/misoc/cores/lasmicon/test_common.py | 106 --- litex/soc/misoc/cores/lasmicon/test_df.py | 40 - litex/soc/misoc/cores/lasmicon/test_lasmi.py | 43 -- .../misoc/cores/lasmicon/test_refresher.py | 47 -- litex/soc/misoc/cores/lasmicon/test_wb.py | 40 - litex/soc/misoc/cores/liteeth_mini/LICENSE | 28 - litex/soc/misoc/cores/liteeth_mini/README | 58 -- litex/soc/misoc/cores/liteeth_mini/common.py | 38 - .../misoc/cores/liteeth_mini/mac/__init__.py | 25 - .../cores/liteeth_mini/mac/core/__init__.py | 100 --- .../misoc/cores/liteeth_mini/mac/core/crc.py | 287 ------- .../misoc/cores/liteeth_mini/mac/core/gap.py | 42 -- .../cores/liteeth_mini/mac/core/last_be.py | 46 -- .../cores/liteeth_mini/mac/core/padding.py | 68 -- .../cores/liteeth_mini/mac/core/preamble.py | 156 ---- .../cores/liteeth_mini/mac/frontend/sram.py | 252 ------- .../liteeth_mini/mac/frontend/wishbone.py | 44 -- .../misoc/cores/liteeth_mini/phy/__init__.py | 23 - .../soc/misoc/cores/liteeth_mini/phy/gmii.py | 98 --- .../misoc/cores/liteeth_mini/phy/gmii_mii.py | 170 ----- .../misoc/cores/liteeth_mini/phy/loopback.py | 35 - litex/soc/misoc/cores/liteeth_mini/phy/mii.py | 110 --- .../misoc/cores/liteeth_mini/phy/s6rgmii.py | 161 ---- litex/soc/misoc/cores/lm32/__init__.py | 1 - litex/soc/misoc/cores/minicon/__init__.py | 1 - litex/soc/misoc/cores/minicon/test.py | 195 ----- litex/soc/misoc/cores/mor1kx/__init__.py | 1 - litex/soc/misoc/cores/mxcrg.v | 247 ------ litex/soc/misoc/cores/sdram_phy/__init__.py | 3 - litex/soc/misoc/cores/spi/__init__.py | 1 - litex/soc/misoc/cores/uart/__init__.py | 1 - litex/soc/misoc/cores/uart/test.py | 97 --- litex/soc/misoc/integration/__init__.py | 2 - litex/soc/misoc/targets/mlabs_video.py | 215 ------ litex/soc/setup.py | 41 - litex/soc/{misoc => }/software/bios/Makefile | 4 +- .../software/bios/boot-helper-lm32.S | 0 .../software/bios/boot-helper-or1k.S | 0 litex/soc/{misoc => }/software/bios/boot.c | 0 litex/soc/{misoc => }/software/bios/boot.h | 0 .../soc/{misoc => }/software/bios/dataflow.c | 0 .../soc/{misoc => }/software/bios/dataflow.h | 0 litex/soc/{misoc => }/software/bios/isr.c | 0 litex/soc/{misoc => }/software/bios/linker.ld | 0 litex/soc/{misoc => }/software/bios/main.c | 5 +- litex/soc/{misoc => }/software/bios/sdram.c | 0 litex/soc/{misoc => }/software/bios/sdram.h | 0 litex/soc/{misoc => }/software/bios/sfl.h | 0 litex/soc/{misoc => }/software/common.mak | 4 +- litex/soc/software/compiler_rt | 1 + .../software/include/base/assert.h | 0 .../software/include/base/console.h | 0 .../{misoc => }/software/include/base/crc.h | 0 .../{misoc => }/software/include/base/ctype.h | 0 .../software/include/base/endian.h | 0 .../{misoc => }/software/include/base/errno.h | 0 .../{misoc => }/software/include/base/float.h | 0 .../{misoc => }/software/include/base/id.h | 0 .../software/include/base/inttypes.h | 0 .../{misoc => }/software/include/base/irq.h | 0 .../software/include/base/limits.h | 0 .../software/include/base/pthread.h | 0 .../software/include/base/spiflash.h | 0 .../software/include/base/spr-defs.h | 0 .../software/include/base/stdarg.h | 0 .../software/include/base/stdbool.h | 0 .../software/include/base/stddef.h | 0 .../software/include/base/stdint.h | 0 .../{misoc => }/software/include/base/stdio.h | 0 .../software/include/base/stdlib.h | 0 .../software/include/base/string.h | 0 .../software/include/base/system.h | 0 .../{misoc => }/software/include/base/time.h | 0 .../{misoc => }/software/include/base/uart.h | 0 .../software/include/basec++/algorithm | 0 .../software/include/basec++/cstddef | 0 .../software/include/basec++/cstdlib | 0 .../{misoc => }/software/include/basec++/new | 0 .../{misoc => }/software/include/dyld/dlfcn.h | 0 .../{misoc => }/software/include/dyld/dyld.h | 0 .../{misoc => }/software/include/dyld/elf.h | 0 .../{misoc => }/software/include/dyld/link.h | 0 .../{misoc => }/software/include/hw/common.h | 0 .../software/include/hw/ethmac_mem.h | 0 .../{misoc => }/software/include/hw/flags.h | 0 .../software/include/net/microudp.h | 0 .../{misoc => }/software/include/net/tftp.h | 0 .../soc/{misoc => }/software/libbase/Makefile | 2 +- .../{misoc => }/software/libbase/console.c | 0 .../soc/{misoc => }/software/libbase/crc16.c | 0 .../soc/{misoc => }/software/libbase/crc32.c | 0 .../{misoc => }/software/libbase/crt0-lm32.S | 0 .../{misoc => }/software/libbase/crt0-or1k.S | 0 .../soc/{misoc => }/software/libbase/errno.c | 0 .../{misoc => }/software/libbase/exception.c | 0 litex/soc/{misoc => }/software/libbase/id.c | 2 +- litex/soc/{misoc => }/software/libbase/libc.c | 0 .../software/libbase/linker-sdram.ld | 0 .../soc/{misoc => }/software/libbase/qsort.c | 0 .../{misoc => }/software/libbase/spiflash.c | 0 .../soc/{misoc => }/software/libbase/strtod.c | 0 .../soc/{misoc => }/software/libbase/system.c | 0 litex/soc/{misoc => }/software/libbase/time.c | 0 litex/soc/{misoc => }/software/libbase/uart.c | 0 .../{misoc => }/software/libbase/vsnprintf.c | 0 .../software/libcompiler_rt/Makefile | 4 +- .../soc/{misoc => }/software/libdyld/Makefile | 4 +- litex/soc/{misoc => }/software/libdyld/dyld.c | 0 .../soc/{misoc => }/software/libnet/Makefile | 2 +- .../{misoc => }/software/libnet/microudp.c | 0 litex/soc/{misoc => }/software/libnet/tftp.c | 0 .../{misoc => }/software/libunwind/Makefile | 10 +- .../software/libunwind/__cxxabi_config.h | 0 .../soc/{misoc => }/software/memtest/Makefile | 0 litex/soc/{misoc => }/software/memtest/isr.c | 0 litex/soc/{misoc => }/software/memtest/main.c | 0 litex/soc/software/unwinder | 1 + .../platforms => litex/soc/tools}/__init__.py | 0 litex/soc/{misoc => }/tools/flterm.py | 0 litex/soc/{misoc => }/tools/mkmscimg.py | 0 migen/__init__.py | 10 - migen/build/altera/__init__.py | 2 - migen/build/altera/common.py | 39 - migen/build/altera/quartus.py | 151 ---- migen/build/fpgalink_programmer.py | 102 --- migen/build/generic_programmer.py | 31 - migen/build/lattice/__init__.py | 2 - migen/build/lattice/common.py | 41 - migen/build/lattice/programmer.py | 54 -- migen/build/openocd.py | 30 - migen/build/platforms/apf27.py | 150 ---- migen/build/platforms/apf51.py | 177 ----- migen/build/platforms/de0nano.py | 103 --- migen/build/platforms/lx9_microboard.py | 131 ---- migen/build/platforms/m1.py | 152 ---- migen/build/platforms/mercury.py | 138 ---- migen/build/platforms/mimasv2.py | 124 --- migen/build/platforms/mixxeo.py | 188 ----- migen/build/platforms/ml605.py | 60 -- migen/build/platforms/papilio_pro.py | 62 -- migen/build/platforms/pipistrello.py | 138 ---- migen/build/platforms/rhino.py | 142 ---- migen/build/platforms/roach.py | 35 - migen/build/platforms/usrp_b100.py | 152 ---- migen/build/platforms/zedboard.py | 145 ---- migen/build/platforms/ztex_115d.py | 110 --- migen/build/sim/__init__.py | 1 - migen/build/sim/common.py | 1 - migen/build/sim/dut_tb.cpp | 399 ---------- migen/build/sim/platform.py | 20 - migen/build/sim/verilator.py | 148 ---- migen/build/tools.py | 42 -- migen/build/xilinx/__init__.py | 2 - migen/build/xilinx/common.py | 150 ---- migen/build/xilinx/ise.py | 198 ----- migen/build/xilinx/platform.py | 33 - migen/build/xilinx/programmer.py | 201 ----- migen/fhdl/__init__.py | 0 migen/fhdl/conv_output.py | 35 - migen/fhdl/decorators.py | 107 --- migen/fhdl/namer.py | 258 ------- migen/fhdl/tools.py | 298 -------- migen/fhdl/tracer.py | 115 --- migen/fhdl/verilog.py | 361 --------- migen/fhdl/visit.py | 202 ----- migen/genlib/__init__.py | 0 migen/genlib/coding.py | 98 --- migen/genlib/fsm.py | 176 ----- migen/genlib/io.py | 96 --- migen/genlib/record.py | 179 ----- migen/genlib/resetsync.py | 18 - migen/genlib/roundrobin.py | 41 - migen/sim/__init__.py | 1 - migen/sim/core.py | 335 -------- migen/test/__init__.py | 0 migen/test/support.py | 13 - migen/test/test_coding.py | 113 --- migen/test/test_constant.py | 29 - migen/test/test_divider.py | 28 - migen/test/test_examples.py | 49 -- migen/test/test_fifo.py | 56 -- migen/test/test_signed.py | 42 -- migen/test/test_size.py | 19 - migen/test/test_sort.py | 30 - migen/test/test_syntax.py | 62 -- migen/util/__init__.py | 0 migen/util/misc.py | 29 - migen/util/treeviz.py | 112 --- setup.py | 26 +- tools/strace_tailor.sh | 16 - 476 files changed, 488 insertions(+), 21806 deletions(-) create mode 100644 .gitmodules delete mode 100644 .travis.yml create mode 100644 MANIFEST.in create mode 100644 README delete mode 100644 README.rst delete mode 100644 conda/migen/bld.bat delete mode 100644 conda/migen/meta.yaml delete mode 100644 doc/Makefile delete mode 100644 doc/_build/.keep_me delete mode 100644 doc/_static/.keep_me delete mode 100644 doc/_templates/.keep_me delete mode 100644 doc/conf.py delete mode 100644 doc/fhdl.rst delete mode 100644 doc/index.rst delete mode 100644 doc/introduction.rst delete mode 100644 doc/migen_logo.png delete mode 100644 doc/migen_logo.svg delete mode 100644 doc/reference.rst delete mode 100644 doc/simulation.rst delete mode 100644 doc/synthesis.rst delete mode 100644 examples/basic/arrays.py delete mode 100644 examples/basic/fsm.py delete mode 100644 examples/basic/graycounter.py delete mode 100644 examples/basic/instance.py delete mode 100644 examples/basic/local_cd.py delete mode 100644 examples/basic/memory.py delete mode 100644 examples/basic/namer.py delete mode 100644 examples/basic/psync.py delete mode 100644 examples/basic/record.py delete mode 100644 examples/basic/reslice.py delete mode 100644 examples/basic/tristate.py delete mode 100644 examples/basic/two_dividers.py delete mode 100644 examples/sim/basic1.py delete mode 100644 examples/sim/basic2.py delete mode 100644 examples/sim/fir.py delete mode 100644 examples/sim/memory.py rename litex/{gen/migen/build => }/__init__.py (100%) rename litex/{gen/migen/build/platforms => boards}/__init__.py (100%) rename litex/{gen/migen/fhdl => boards/platforms}/__init__.py (100%) rename litex/{gen/migen/build => boards}/platforms/de0nano.py (95%) rename {migen/build => litex/boards}/platforms/kc705.py (98%) rename {migen/build => litex/boards}/platforms/minispartan6.py (96%) rename {migen/build => litex/boards}/platforms/sim.py (92%) rename {migen/build => litex/boards}/platforms/versa.py (95%) rename litex/{gen/migen/genlib => boards/targets}/__init__.py (100%) rename litex/{soc/misoc => boards}/targets/de0nano.py (91%) rename litex/{soc/misoc => boards}/targets/kc705.py (90%) rename litex/{soc/misoc => boards}/targets/minispartan6.py (90%) rename litex/{soc/misoc => boards}/targets/papilio_pro.py (90%) rename litex/{soc/misoc => boards}/targets/pipistrello.py (93%) rename litex/{soc/misoc => boards}/targets/simple.py (83%) rename litex/{gen/migen/test => build}/__init__.py (100%) create mode 100644 litex/build/altera/__init__.py rename litex/{gen/migen => }/build/altera/common.py (86%) rename {migen => litex}/build/altera/platform.py (89%) rename {migen => litex}/build/altera/programmer.py (85%) rename litex/{gen/migen => }/build/altera/quartus.py (96%) rename {migen => litex}/build/generic_platform.py (98%) rename litex/{gen/migen => }/build/generic_programmer.py (86%) create mode 100644 litex/build/lattice/__init__.py rename litex/{gen/migen => }/build/lattice/common.py (84%) rename {migen => litex}/build/lattice/diamond.py (94%) rename {migen => litex}/build/lattice/platform.py (89%) rename litex/{gen/migen => }/build/lattice/programmer.py (94%) rename litex/{gen/migen => }/build/openocd.py (93%) create mode 100644 litex/build/sim/__init__.py rename litex/{gen/migen => }/build/sim/common.py (100%) rename litex/{gen/migen => }/build/sim/dut_tb.cpp (100%) rename litex/{gen/migen => }/build/sim/platform.py (86%) rename litex/{gen/migen => }/build/sim/verilator.py (96%) rename litex/{gen/migen => }/build/tools.py (100%) create mode 100644 litex/build/xilinx/__init__.py rename litex/{gen/migen => }/build/xilinx/common.py (91%) rename litex/{gen/migen => }/build/xilinx/ise.py (96%) rename litex/{gen/migen => }/build/xilinx/platform.py (91%) rename litex/{gen/migen => }/build/xilinx/programmer.py (98%) rename {migen => litex}/build/xilinx/vivado.py (95%) delete mode 100644 litex/gen/.gitignore delete mode 100644 litex/gen/.travis.yml delete mode 100644 litex/gen/LICENSE rename LICENSE => litex/gen/MIGEN_LICENSE (100%) delete mode 100644 litex/gen/README.rst create mode 100644 litex/gen/__init__.py delete mode 100644 litex/gen/conda/migen/bld.bat delete mode 100644 litex/gen/conda/migen/meta.yaml delete mode 100644 litex/gen/doc/Makefile delete mode 100644 litex/gen/doc/_static/.keep_me delete mode 100644 litex/gen/doc/_templates/.keep_me delete mode 100644 litex/gen/doc/conf.py delete mode 100644 litex/gen/doc/fhdl.rst delete mode 100644 litex/gen/doc/index.rst delete mode 100644 litex/gen/doc/introduction.rst delete mode 100644 litex/gen/doc/migen_logo.png delete mode 100644 litex/gen/doc/migen_logo.svg delete mode 100644 litex/gen/doc/reference.rst delete mode 100644 litex/gen/doc/simulation.rst delete mode 100644 litex/gen/doc/synthesis.rst delete mode 100644 litex/gen/examples/basic/arrays.py delete mode 100644 litex/gen/examples/basic/fsm.py delete mode 100644 litex/gen/examples/basic/graycounter.py delete mode 100644 litex/gen/examples/basic/instance.py delete mode 100644 litex/gen/examples/basic/local_cd.py delete mode 100644 litex/gen/examples/basic/memory.py delete mode 100644 litex/gen/examples/basic/namer.py delete mode 100644 litex/gen/examples/basic/psync.py delete mode 100644 litex/gen/examples/basic/record.py delete mode 100644 litex/gen/examples/basic/reslice.py delete mode 100644 litex/gen/examples/basic/tristate.py delete mode 100644 litex/gen/examples/basic/two_dividers.py delete mode 100644 litex/gen/examples/sim/basic1.py delete mode 100644 litex/gen/examples/sim/basic2.py delete mode 100644 litex/gen/examples/sim/fir.py delete mode 100644 litex/gen/examples/sim/memory.py rename litex/gen/{migen/util => fhdl}/__init__.py (100%) rename {migen => litex/gen}/fhdl/bitcontainer.py (98%) rename litex/gen/{migen => }/fhdl/conv_output.py (100%) rename litex/gen/{migen => }/fhdl/decorators.py (95%) rename {migen => litex/gen}/fhdl/edif.py (96%) rename {migen => litex/gen}/fhdl/module.py (96%) rename litex/gen/{migen => }/fhdl/namer.py (98%) rename {migen => litex/gen}/fhdl/simplify.py (95%) rename {migen => litex/gen}/fhdl/specials.py (97%) rename {migen => litex/gen}/fhdl/structure.py (98%) rename litex/gen/{migen => }/fhdl/tools.py (96%) rename litex/gen/{migen => }/fhdl/tracer.py (100%) rename litex/gen/{migen => }/fhdl/verilog.py (97%) rename litex/gen/{migen => }/fhdl/visit.py (98%) rename litex/{soc/misoc => gen/genlib}/__init__.py (100%) rename {migen => litex/gen}/genlib/cdc.py (94%) rename litex/gen/{migen => }/genlib/coding.py (96%) rename {migen => litex/gen}/genlib/divider.py (92%) rename {migen => litex/gen}/genlib/fifo.py (95%) rename litex/gen/{migen => }/genlib/fsm.py (95%) rename litex/gen/{migen => }/genlib/io.py (95%) rename {migen => litex/gen}/genlib/misc.py (94%) rename litex/gen/{migen => }/genlib/record.py (98%) rename litex/gen/{migen => }/genlib/resetsync.py (85%) rename litex/gen/{migen => }/genlib/roundrobin.py (93%) rename {migen => litex/gen}/genlib/sort.py (96%) delete mode 100644 litex/gen/migen/__init__.py delete mode 100644 litex/gen/migen/build/altera/__init__.py delete mode 100644 litex/gen/migen/build/altera/platform.py delete mode 100644 litex/gen/migen/build/altera/programmer.py delete mode 100644 litex/gen/migen/build/fpgalink_programmer.py delete mode 100644 litex/gen/migen/build/generic_platform.py delete mode 100644 litex/gen/migen/build/lattice/__init__.py delete mode 100644 litex/gen/migen/build/lattice/diamond.py delete mode 100644 litex/gen/migen/build/lattice/platform.py delete mode 100644 litex/gen/migen/build/platforms/apf27.py delete mode 100644 litex/gen/migen/build/platforms/apf51.py delete mode 100644 litex/gen/migen/build/platforms/kc705.py delete mode 100644 litex/gen/migen/build/platforms/lx9_microboard.py delete mode 100644 litex/gen/migen/build/platforms/m1.py delete mode 100644 litex/gen/migen/build/platforms/mercury.py delete mode 100644 litex/gen/migen/build/platforms/mimasv2.py delete mode 100644 litex/gen/migen/build/platforms/minispartan6.py delete mode 100644 litex/gen/migen/build/platforms/mixxeo.py delete mode 100644 litex/gen/migen/build/platforms/ml605.py delete mode 100644 litex/gen/migen/build/platforms/papilio_pro.py delete mode 100644 litex/gen/migen/build/platforms/pipistrello.py delete mode 100644 litex/gen/migen/build/platforms/rhino.py delete mode 100644 litex/gen/migen/build/platforms/roach.py delete mode 100644 litex/gen/migen/build/platforms/sim.py delete mode 100644 litex/gen/migen/build/platforms/usrp_b100.py delete mode 100644 litex/gen/migen/build/platforms/versa.py delete mode 100644 litex/gen/migen/build/platforms/zedboard.py delete mode 100644 litex/gen/migen/build/platforms/ztex_115d.py delete mode 100644 litex/gen/migen/build/sim/__init__.py delete mode 100644 litex/gen/migen/build/xilinx/__init__.py delete mode 100644 litex/gen/migen/build/xilinx/vivado.py delete mode 100644 litex/gen/migen/fhdl/bitcontainer.py delete mode 100644 litex/gen/migen/fhdl/edif.py delete mode 100644 litex/gen/migen/fhdl/module.py delete mode 100644 litex/gen/migen/fhdl/simplify.py delete mode 100644 litex/gen/migen/fhdl/specials.py delete mode 100644 litex/gen/migen/fhdl/structure.py delete mode 100644 litex/gen/migen/genlib/cdc.py delete mode 100644 litex/gen/migen/genlib/divider.py delete mode 100644 litex/gen/migen/genlib/fifo.py delete mode 100644 litex/gen/migen/genlib/misc.py delete mode 100644 litex/gen/migen/genlib/sort.py delete mode 100644 litex/gen/migen/sim/__init__.py delete mode 100644 litex/gen/migen/sim/vcd.py delete mode 100644 litex/gen/migen/test/support.py delete mode 100644 litex/gen/migen/test/test_coding.py delete mode 100644 litex/gen/migen/test/test_constant.py delete mode 100644 litex/gen/migen/test/test_divider.py delete mode 100644 litex/gen/migen/test/test_examples.py delete mode 100644 litex/gen/migen/test/test_fifo.py delete mode 100644 litex/gen/migen/test/test_signed.py delete mode 100644 litex/gen/migen/test/test_size.py delete mode 100644 litex/gen/migen/test/test_sort.py delete mode 100644 litex/gen/migen/test/test_syntax.py delete mode 100644 litex/gen/migen/util/treeviz.py delete mode 100644 litex/gen/setup.py create mode 100644 litex/gen/sim/__init__.py rename litex/gen/{migen => }/sim/core.py (96%) rename {migen => litex/gen}/sim/vcd.py (97%) delete mode 100644 litex/gen/tools/strace_tailor.sh rename litex/{soc/misoc/cores => gen/util}/__init__.py (100%) rename litex/gen/{migen => }/util/misc.py (100%) delete mode 100644 litex/soc/.gitignore delete mode 100644 litex/soc/.gitmodules delete mode 100644 litex/soc/.travis.yml delete mode 100644 litex/soc/CONTRIBUTING.rst delete mode 100644 litex/soc/MANIFEST.in rename litex/soc/{LICENSE => MISOC_LICENSE} (100%) delete mode 100644 litex/soc/README rename litex/soc/{misoc/cores/liteeth_mini => }/__init__.py (100%) delete mode 100644 litex/soc/conda/misoc/bld.bat delete mode 100644 litex/soc/conda/misoc/meta.yaml rename litex/soc/{misoc/cores/liteeth_mini/mac/frontend => cores}/__init__.py (100%) rename litex/soc/{misoc/interconnect => cores/cpu}/__init__.py (100%) create mode 100644 litex/soc/cores/cpu/lm32/__init__.py rename litex/soc/{misoc/cores => cores/cpu}/lm32/core.py (97%) rename litex/soc/{misoc/cores => cores/cpu}/lm32/verilog/lm32_config.v (100%) create mode 160000 litex/soc/cores/cpu/lm32/verilog/submodule create mode 100644 litex/soc/cores/cpu/mor1kx/__init__.py rename litex/soc/{misoc/cores => cores/cpu}/mor1kx/core.py (98%) create mode 160000 litex/soc/cores/cpu/mor1kx/verilog rename litex/soc/{misoc/targets => cores/flash}/__init__.py (100%) rename litex/soc/{misoc/cores => cores/flash}/nor_flash_16.py (96%) rename litex/soc/{misoc/cores => cores/flash}/spi_flash.py (95%) rename litex/soc/{misoc => }/cores/gpio.py (88%) rename litex/soc/{misoc => }/cores/identifier.py (82%) rename litex/soc/{misoc/tools => cores/sdram}/__init__.py (100%) rename litex/soc/{misoc/cores => cores/sdram}/dfii.py (96%) create mode 100644 litex/soc/cores/sdram/lasmicon/__init__.py rename litex/soc/{misoc/cores => cores/sdram}/lasmicon/bankmachine.py (95%) rename litex/soc/{misoc/cores => cores/sdram}/lasmicon/core.py (89%) rename litex/soc/{misoc/cores => cores/sdram}/lasmicon/multiplexer.py (97%) rename litex/soc/{misoc/cores => cores/sdram}/lasmicon/perf.py (95%) rename litex/soc/{misoc/cores => cores/sdram}/lasmicon/refresher.py (91%) create mode 100644 litex/soc/cores/sdram/minicon/__init__.py rename litex/soc/{misoc/cores => cores/sdram}/minicon/core.py (97%) rename litex/soc/{misoc/cores/sdram_model.py => cores/sdram/model.py} (96%) create mode 100644 litex/soc/cores/sdram/phy/__init__.py rename litex/soc/{misoc/cores/sdram_phy => cores/sdram/phy}/gensdrphy.py (92%) rename litex/soc/{misoc/cores/sdram_phy => cores/sdram/phy}/k7ddrphy.py (98%) rename litex/soc/{misoc/cores/sdram_phy => cores/sdram/phy}/s6ddrphy.py (99%) rename litex/soc/{misoc/cores/sdram_settings.py => cores/sdram/settings.py} (99%) rename litex/soc/{misoc/cores/sdram_tester.py => cores/sdram/tester.py} (94%) create mode 100644 litex/soc/cores/spi/__init__.py rename litex/soc/{misoc => }/cores/spi/core.py (97%) rename litex/soc/{misoc => }/cores/spi/test.py (93%) rename litex/soc/{misoc => }/cores/timer.py (88%) create mode 100644 litex/soc/cores/uart/__init__.py rename litex/soc/{misoc => }/cores/uart/core.py (94%) create mode 100644 litex/soc/integration/__init__.py rename litex/soc/{misoc => }/integration/builder.py (93%) rename litex/soc/{misoc => }/integration/cpu_interface.py (98%) rename litex/soc/{misoc => }/integration/sdram_init.py (99%) rename litex/soc/{misoc => }/integration/soc_core.py (97%) rename litex/soc/{misoc => }/integration/soc_sdram.py (90%) rename {migen/build => litex/soc/interconnect}/__init__.py (100%) rename litex/soc/{misoc => }/interconnect/csr.py (97%) rename litex/soc/{misoc => }/interconnect/csr_bus.py (96%) rename litex/soc/{misoc => }/interconnect/csr_eventmanager.py (96%) rename litex/soc/{misoc => }/interconnect/dfi.py (97%) rename litex/soc/{misoc => }/interconnect/dma_lasmi.py (97%) rename litex/soc/{misoc => }/interconnect/lasmi_bus.py (98%) rename litex/soc/{misoc => }/interconnect/stream.py (98%) rename litex/soc/{misoc => }/interconnect/wishbone.py (97%) rename litex/soc/{misoc => }/interconnect/wishbone2csr.py (86%) rename litex/soc/{misoc => }/interconnect/wishbone2lasmi.py (94%) delete mode 100644 litex/soc/misoc/cores/dvi_sampler/__init__.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/analysis.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/chansync.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/charsync.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/clocking.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/common.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/core.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/datacapture.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/debug.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/decoding.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/dma.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/edid.py delete mode 100644 litex/soc/misoc/cores/dvi_sampler/wer.py delete mode 100644 litex/soc/misoc/cores/framebuffer/__init__.py delete mode 100644 litex/soc/misoc/cores/framebuffer/core.py delete mode 100644 litex/soc/misoc/cores/framebuffer/dvi.py delete mode 100644 litex/soc/misoc/cores/framebuffer/format.py delete mode 100644 litex/soc/misoc/cores/framebuffer/phy.py delete mode 100644 litex/soc/misoc/cores/lasmicon/__init__.py delete mode 100644 litex/soc/misoc/cores/lasmicon/test_bankmachine.py delete mode 100644 litex/soc/misoc/cores/lasmicon/test_common.py delete mode 100644 litex/soc/misoc/cores/lasmicon/test_df.py delete mode 100644 litex/soc/misoc/cores/lasmicon/test_lasmi.py delete mode 100644 litex/soc/misoc/cores/lasmicon/test_refresher.py delete mode 100644 litex/soc/misoc/cores/lasmicon/test_wb.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/LICENSE delete mode 100644 litex/soc/misoc/cores/liteeth_mini/README delete mode 100644 litex/soc/misoc/cores/liteeth_mini/common.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/__init__.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/core/__init__.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/core/crc.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/core/gap.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/core/last_be.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/core/padding.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/core/preamble.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/frontend/sram.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/mac/frontend/wishbone.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/phy/__init__.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/phy/gmii.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/phy/gmii_mii.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/phy/loopback.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/phy/mii.py delete mode 100644 litex/soc/misoc/cores/liteeth_mini/phy/s6rgmii.py delete mode 100644 litex/soc/misoc/cores/lm32/__init__.py delete mode 100644 litex/soc/misoc/cores/minicon/__init__.py delete mode 100644 litex/soc/misoc/cores/minicon/test.py delete mode 100644 litex/soc/misoc/cores/mor1kx/__init__.py delete mode 100644 litex/soc/misoc/cores/mxcrg.v delete mode 100644 litex/soc/misoc/cores/sdram_phy/__init__.py delete mode 100644 litex/soc/misoc/cores/spi/__init__.py delete mode 100644 litex/soc/misoc/cores/uart/__init__.py delete mode 100644 litex/soc/misoc/cores/uart/test.py delete mode 100644 litex/soc/misoc/integration/__init__.py delete mode 100644 litex/soc/misoc/targets/mlabs_video.py delete mode 100644 litex/soc/setup.py rename litex/soc/{misoc => }/software/bios/Makefile (87%) rename litex/soc/{misoc => }/software/bios/boot-helper-lm32.S (100%) rename litex/soc/{misoc => }/software/bios/boot-helper-or1k.S (100%) rename litex/soc/{misoc => }/software/bios/boot.c (100%) rename litex/soc/{misoc => }/software/bios/boot.h (100%) rename litex/soc/{misoc => }/software/bios/dataflow.c (100%) rename litex/soc/{misoc => }/software/bios/dataflow.h (100%) rename litex/soc/{misoc => }/software/bios/isr.c (100%) rename litex/soc/{misoc => }/software/bios/linker.ld (100%) rename litex/soc/{misoc => }/software/bios/main.c (99%) rename litex/soc/{misoc => }/software/bios/sdram.c (100%) rename litex/soc/{misoc => }/software/bios/sdram.h (100%) rename litex/soc/{misoc => }/software/bios/sfl.h (100%) rename litex/soc/{misoc => }/software/common.mak (84%) create mode 160000 litex/soc/software/compiler_rt rename litex/soc/{misoc => }/software/include/base/assert.h (100%) rename litex/soc/{misoc => }/software/include/base/console.h (100%) rename litex/soc/{misoc => }/software/include/base/crc.h (100%) rename litex/soc/{misoc => }/software/include/base/ctype.h (100%) rename litex/soc/{misoc => }/software/include/base/endian.h (100%) rename litex/soc/{misoc => }/software/include/base/errno.h (100%) rename litex/soc/{misoc => }/software/include/base/float.h (100%) rename litex/soc/{misoc => }/software/include/base/id.h (100%) rename litex/soc/{misoc => }/software/include/base/inttypes.h (100%) rename litex/soc/{misoc => }/software/include/base/irq.h (100%) rename litex/soc/{misoc => }/software/include/base/limits.h (100%) rename litex/soc/{misoc => }/software/include/base/pthread.h (100%) rename litex/soc/{misoc => }/software/include/base/spiflash.h (100%) rename litex/soc/{misoc => }/software/include/base/spr-defs.h (100%) rename litex/soc/{misoc => }/software/include/base/stdarg.h (100%) rename litex/soc/{misoc => }/software/include/base/stdbool.h (100%) rename litex/soc/{misoc => }/software/include/base/stddef.h (100%) rename litex/soc/{misoc => }/software/include/base/stdint.h (100%) rename litex/soc/{misoc => }/software/include/base/stdio.h (100%) rename litex/soc/{misoc => }/software/include/base/stdlib.h (100%) rename litex/soc/{misoc => }/software/include/base/string.h (100%) rename litex/soc/{misoc => }/software/include/base/system.h (100%) rename litex/soc/{misoc => }/software/include/base/time.h (100%) rename litex/soc/{misoc => }/software/include/base/uart.h (100%) rename litex/soc/{misoc => }/software/include/basec++/algorithm (100%) rename litex/soc/{misoc => }/software/include/basec++/cstddef (100%) rename litex/soc/{misoc => }/software/include/basec++/cstdlib (100%) rename litex/soc/{misoc => }/software/include/basec++/new (100%) rename litex/soc/{misoc => }/software/include/dyld/dlfcn.h (100%) rename litex/soc/{misoc => }/software/include/dyld/dyld.h (100%) rename litex/soc/{misoc => }/software/include/dyld/elf.h (100%) rename litex/soc/{misoc => }/software/include/dyld/link.h (100%) rename litex/soc/{misoc => }/software/include/hw/common.h (100%) rename litex/soc/{misoc => }/software/include/hw/ethmac_mem.h (100%) rename litex/soc/{misoc => }/software/include/hw/flags.h (100%) rename litex/soc/{misoc => }/software/include/net/microudp.h (100%) rename litex/soc/{misoc => }/software/include/net/tftp.h (100%) rename litex/soc/{misoc => }/software/libbase/Makefile (93%) rename litex/soc/{misoc => }/software/libbase/console.c (100%) rename litex/soc/{misoc => }/software/libbase/crc16.c (100%) rename litex/soc/{misoc => }/software/libbase/crc32.c (100%) rename litex/soc/{misoc => }/software/libbase/crt0-lm32.S (100%) rename litex/soc/{misoc => }/software/libbase/crt0-or1k.S (100%) rename litex/soc/{misoc => }/software/libbase/errno.c (100%) rename litex/soc/{misoc => }/software/libbase/exception.c (100%) rename litex/soc/{misoc => }/software/libbase/id.c (75%) rename litex/soc/{misoc => }/software/libbase/libc.c (100%) rename litex/soc/{misoc => }/software/libbase/linker-sdram.ld (100%) rename litex/soc/{misoc => }/software/libbase/qsort.c (100%) rename litex/soc/{misoc => }/software/libbase/spiflash.c (100%) rename litex/soc/{misoc => }/software/libbase/strtod.c (100%) rename litex/soc/{misoc => }/software/libbase/system.c (100%) rename litex/soc/{misoc => }/software/libbase/time.c (100%) rename litex/soc/{misoc => }/software/libbase/uart.c (100%) rename litex/soc/{misoc => }/software/libbase/vsnprintf.c (100%) rename litex/soc/{misoc => }/software/libcompiler_rt/Makefile (87%) rename litex/soc/{misoc => }/software/libdyld/Makefile (75%) rename litex/soc/{misoc => }/software/libdyld/dyld.c (100%) rename litex/soc/{misoc => }/software/libnet/Makefile (84%) rename litex/soc/{misoc => }/software/libnet/microudp.c (100%) rename litex/soc/{misoc => }/software/libnet/tftp.c (100%) rename litex/soc/{misoc => }/software/libunwind/Makefile (63%) rename litex/soc/{misoc => }/software/libunwind/__cxxabi_config.h (100%) rename litex/soc/{misoc => }/software/memtest/Makefile (100%) rename litex/soc/{misoc => }/software/memtest/isr.c (100%) rename litex/soc/{misoc => }/software/memtest/main.c (100%) create mode 160000 litex/soc/software/unwinder rename {migen/build/platforms => litex/soc/tools}/__init__.py (100%) rename litex/soc/{misoc => }/tools/flterm.py (100%) rename litex/soc/{misoc => }/tools/mkmscimg.py (100%) delete mode 100644 migen/__init__.py delete mode 100644 migen/build/altera/__init__.py delete mode 100644 migen/build/altera/common.py delete mode 100644 migen/build/altera/quartus.py delete mode 100644 migen/build/fpgalink_programmer.py delete mode 100644 migen/build/generic_programmer.py delete mode 100644 migen/build/lattice/__init__.py delete mode 100644 migen/build/lattice/common.py delete mode 100644 migen/build/lattice/programmer.py delete mode 100644 migen/build/openocd.py delete mode 100644 migen/build/platforms/apf27.py delete mode 100644 migen/build/platforms/apf51.py delete mode 100644 migen/build/platforms/de0nano.py delete mode 100644 migen/build/platforms/lx9_microboard.py delete mode 100644 migen/build/platforms/m1.py delete mode 100644 migen/build/platforms/mercury.py delete mode 100644 migen/build/platforms/mimasv2.py delete mode 100644 migen/build/platforms/mixxeo.py delete mode 100644 migen/build/platforms/ml605.py delete mode 100644 migen/build/platforms/papilio_pro.py delete mode 100644 migen/build/platforms/pipistrello.py delete mode 100644 migen/build/platforms/rhino.py delete mode 100644 migen/build/platforms/roach.py delete mode 100644 migen/build/platforms/usrp_b100.py delete mode 100644 migen/build/platforms/zedboard.py delete mode 100644 migen/build/platforms/ztex_115d.py delete mode 100644 migen/build/sim/__init__.py delete mode 100644 migen/build/sim/common.py delete mode 100644 migen/build/sim/dut_tb.cpp delete mode 100644 migen/build/sim/platform.py delete mode 100644 migen/build/sim/verilator.py delete mode 100644 migen/build/tools.py delete mode 100644 migen/build/xilinx/__init__.py delete mode 100644 migen/build/xilinx/common.py delete mode 100644 migen/build/xilinx/ise.py delete mode 100644 migen/build/xilinx/platform.py delete mode 100644 migen/build/xilinx/programmer.py delete mode 100644 migen/fhdl/__init__.py delete mode 100644 migen/fhdl/conv_output.py delete mode 100644 migen/fhdl/decorators.py delete mode 100644 migen/fhdl/namer.py delete mode 100644 migen/fhdl/tools.py delete mode 100644 migen/fhdl/tracer.py delete mode 100644 migen/fhdl/verilog.py delete mode 100644 migen/fhdl/visit.py delete mode 100644 migen/genlib/__init__.py delete mode 100644 migen/genlib/coding.py delete mode 100644 migen/genlib/fsm.py delete mode 100644 migen/genlib/io.py delete mode 100644 migen/genlib/record.py delete mode 100644 migen/genlib/resetsync.py delete mode 100644 migen/genlib/roundrobin.py delete mode 100644 migen/sim/__init__.py delete mode 100644 migen/sim/core.py delete mode 100644 migen/test/__init__.py delete mode 100644 migen/test/support.py delete mode 100644 migen/test/test_coding.py delete mode 100644 migen/test/test_constant.py delete mode 100644 migen/test/test_divider.py delete mode 100644 migen/test/test_examples.py delete mode 100644 migen/test/test_fifo.py delete mode 100644 migen/test/test_signed.py delete mode 100644 migen/test/test_size.py delete mode 100644 migen/test/test_sort.py delete mode 100644 migen/test/test_syntax.py delete mode 100644 migen/util/__init__.py delete mode 100644 migen/util/misc.py delete mode 100644 migen/util/treeviz.py delete mode 100755 tools/strace_tailor.sh diff --git a/.gitignore b/.gitignore index 3fa21c42..9e102e66 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ __pycache__ *.pyc -*.egg-info/ -vpi/*.o -vpi/migensim.vpi -examples/*.vcd -doc/_build +*.egg-info +*.vcd +outgoing diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 00000000..0aff80a1 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,12 @@ +[submodule "litex/soc/cores/cpu/lm32/verilog/submodule"] + path = litex/soc/cores/cpu/lm32/verilog/submodule + url = https://github.com/m-labs/lm32.git +[submodule "litex/soc/cores/cpu/mor1kx/verilog"] + path = litex/soc/cores/cpu/mor1kx/verilog + url = https://github.com/openrisc/mor1kx.git +[submodule "litex/soc/software/compiler_rt"] + path = litex/soc/software/compiler_rt + url = http://llvm.org/git/compiler-rt.git +[submodule "litex/soc/software/unwinder"] + path = litex/soc/software/unwinder + url = https://github.com/whitequark/libunwind diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 315850e3..00000000 --- a/.travis.yml +++ /dev/null @@ -1,52 +0,0 @@ -language: python -python: - - "3.5" - -env: - global: - - PATH=$HOME/miniconda/bin:$PATH - -before_install: - # Install Miniconda - - wget https://raw.githubusercontent.com/m-labs/artiq/master/.travis/get-anaconda.sh - - chmod +x get-anaconda.sh - - ./get-anaconda.sh - - source $HOME/miniconda/bin/activate py35 - - conda install anaconda-client numpydoc -install: - # Install iverilog package. - # - "sudo add-apt-repository -y ppa:mithro/iverilog-backport" - # - "sudo apt-get update" - # - "sudo apt-get install iverilog" - # - "iverilog -v; true" - # Build the vpi module. - # - "(cd vpi; make; sudo make install)" - # Install verilator package - - "sudo apt-get install verilator" - - "verilator --version; true" - # Build and install Migen conda package - # workaround for https://github.com/conda/conda-build/issues/466 - - "mkdir -p /home/travis/miniconda/conda-bld/linux-64" - - "conda index /home/travis/miniconda/conda-bld/linux-64" - - "conda build --python 3.5 conda/migen" - - "conda install $(conda build --output --python 3.5 conda/migen)" - -script: - # Run tests - - "python setup.py test" - # Generate HTML documentation - - "make -C doc html" - -after_success: - # Upload Migen conda package to binstar - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda login --hostname $(hostname) --username $binstar_login --password $binstar_password; fi - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda upload --user $binstar_login --channel dev --force $HOME/miniconda/conda-bld/noarch/migen-*.tar.bz2; fi - -notifications: - email: false - irc: - channels: - - chat.freenode.net#m-labs - template: - - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}" - - "Build details : %{build_url}" diff --git a/MANIFEST.in b/MANIFEST.in new file mode 100644 index 00000000..701237de --- /dev/null +++ b/MANIFEST.in @@ -0,0 +1,3 @@ +graft litex/soc/software +graft litex/soc/cores/cpu/lm32/verilog +graft litex/soc/cores/cpu/mor1kx/verilog diff --git a/README b/README new file mode 100644 index 00000000..6eff1b4e --- /dev/null +++ b/README @@ -0,0 +1,42 @@ + __ _ __ _ __ + / / (_) /____ | |/_/ + / /__/ / __/ -_)> < + /____/_/\__/\__/_/|_| + + Build your hardware, easily! + Copyright 2015 Enjoy-Digital + (based on Migen/MiSoC technologies) + +[> Intro +--------- +LiteX is a fork of Migen/MiSoC for our own needs at Enjoy-Digital. It provides +a single python package and add some specific features to design our FPGA cores, +build a SoC with or or load/flash it to the hardware. + +The structure of LiteX is kept close to Migen/MiSoC to enable collaboration +between projects. + +[> License +----------- +LiteX is copyright (c) 2015 Enjoy-Digital. +Since it is based on Migen/MiSoC, see gen/MIGEN_LICENSE and soc/MISOC_LICENSE or +git history to get correct ownership of files. + +[> Sub-packages +----------- +gen: + Provides tools and simple modules to generate HDL. + +build: + Provides tools to build FPGA bitstreams (interface to vendor toolchains) and to + simulate HDL code or full SoCs. + +soc: + Provides definitions/modules to build cores (bus, bank, flow), cores and tools + to build a SoC from such cores. + +boards: + Provides platforms and targets for the supported boards. + +[> Contact +E-mail: florent [AT] enjoy-digital.fr \ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index 39f8e96a..00000000 --- a/README.rst +++ /dev/null @@ -1,82 +0,0 @@ -### Migen (Milkymist generator) - -[![Build Status](https://travis-ci.org/m-labs/migen.svg)]( -https://travis-ci.org/m-labs/migen) - -#### A Python toolbox for building complex digital hardware - -Despite being faster than schematics entry, hardware design with Verilog and -VHDL remains tedious and inefficient for several reasons. The event-driven -model introduces issues and manual coding that are unnecessary for synchronous -circuits, which represent the lion's share of today's logic designs. Counter- -intuitive arithmetic rules result in steeper learning curves and provide a -fertile ground for subtle bugs in designs. Finally, support for procedural -generation of logic (metaprogramming) through "generate" statements is very -limited and restricts the ways code can be made generic, reused and organized. - -To address those issues, we have developed the **Migen FHDL** library that -replaces the event-driven paradigm with the notions of combinatorial and -synchronous statements, has arithmetic rules that make integers always behave -like mathematical integers, and most importantly allows the design's logic to -be constructed by a Python program. This last point enables hardware designers -to take advantage of the richness of the Python language - object oriented -programming, function parameters, generators, operator overloading, libraries, -etc. - to build well organized, reusable and elegant designs. - -Other Migen libraries are built on FHDL and provide various tools such as a -system-on-chip interconnect infrastructure, a dataflow programming system, a -more traditional high-level synthesizer that compiles Python routines into -state machines with datapaths, and a simulator that allows test benches to be -written in Python. - -See the doc/ folder for more technical information. - -Migen is designed for Python 3.3. Note that Migen is **not** spelled MiGen. - -#### Quick Links - -Code repository: -https://github.com/m-labs/migen - -System-on-chip design based on Migen: -https://github.com/m-labs/misoc - -Online documentation: -http://m-labs.hk/gateware.html - -#### Quick intro - -```python -from migen import * -from migen.build.platforms import m1 -plat = m1.Platform() -led = plat.request("user_led") -m = Module() -counter = Signal(26) -m.comb += led.eq(counter[25]) -m.sync += counter.eq(counter + 1) -plat.build_cmdline(m) -``` - -#### License - -Migen is released under the very permissive two-clause BSD license. Under the -terms of this license, you are authorized to use Migen 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 Migen -* put the Migen logo (doc/migen_logo.svg) on the page of a product using it, - with a link to http://m-labs.hk -* cite Migen 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 Migen. 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 (#m-labs on Freenode) beforehand. - -See LICENSE file for full copyright and license info. You can contact us on the -public mailing list devel [AT] lists.m-labs.hk. - - "Electricity! It's like magic!" diff --git a/conda/migen/bld.bat b/conda/migen/bld.bat deleted file mode 100644 index 39b5e1fe..00000000 --- a/conda/migen/bld.bat +++ /dev/null @@ -1 +0,0 @@ -%PYTHON% setup.py install diff --git a/conda/migen/meta.yaml b/conda/migen/meta.yaml deleted file mode 100644 index 1cf9baee..00000000 --- a/conda/migen/meta.yaml +++ /dev/null @@ -1,28 +0,0 @@ -package: - name: migen - version: {{ environ.get("GIT_DESCRIBE_TAG", "") }} - -source: - git_url: https://github.com/m-labs/migen - git_tag: master - -build: - noarch_python: true - number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }} - string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }} - script: $PYTHON setup.py install - -requirements: - build: - - python 3.5.* - run: - - python 3.5.* - -test: - imports: - - migen - -about: - home: http://m-labs.hk/gateware.html - license: 3-clause BSD - summary: 'A Python toolbox for building complex digital hardware' diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index d6a5924b..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Migen.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Migen.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Migen" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Migen" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/doc/_build/.keep_me b/doc/_build/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/_static/.keep_me b/doc/_static/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/_templates/.keep_me b/doc/_templates/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/conf.py b/doc/conf.py deleted file mode 100644 index f134ce9b..00000000 --- a/doc/conf.py +++ /dev/null @@ -1,223 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Migen documentation build configuration file, created by -# sphinx-quickstart on Fri Mar 9 14:11:54 2012. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.pngmath', - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.autosummary', - 'numpydoc', # to preprocess docstrings - ] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Migen' -copyright = u'2011-2015, M-Labs Limited' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0' -# The full version, including alpha/beta/rc tags. -release = '1.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['migen.'] - -numpydoc_show_class_members = False - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Migendoc' - -html_use_modindex = False - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'Migen.tex', u'Migen manual', - u'Sebastien Bourdeauducq', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -latex_logo = "migen_logo.png" - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -latex_preamble = '\setcounter{tocdepth}{3}' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - -latex_use_modindex = False - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'migen', u'Migen manual', - [u'Sebastien Bourdeauducq'], 1) -] diff --git a/doc/fhdl.rst b/doc/fhdl.rst deleted file mode 100644 index b6225605..00000000 --- a/doc/fhdl.rst +++ /dev/null @@ -1,362 +0,0 @@ -The FHDL domain-specific language -################################# - -The Fragmented Hardware Description Language (FHDL) is the basis of Migen. It consists of a formal system to describe signals, and combinatorial and synchronous statements operating on them. The formal system itself is low level and close to the synthesizable subset of Verilog, and we then rely on Python algorithms to build complex structures by combining FHDL elements. -The FHDL module also contains a back-end to produce synthesizable Verilog, and some structure analysis and manipulation functionality. - -FHDL differs from MyHDL [myhdl]_ in fundamental ways. MyHDL follows the event-driven paradigm of traditional HDLs (see :ref:`background`) while FHDL separates the code into combinatorial statements, synchronous statements, and reset values. In MyHDL, the logic is described directly in the Python AST. The converter to Verilog or VHDL then examines the Python AST and recognizes a subset of Python that it translates into V*HDL statements. This seriously impedes the capability of MyHDL to generate logic procedurally. With FHDL, you manipulate a custom AST from Python, and you can more easily design algorithms that operate on it. - -.. [myhdl] http://www.myhdl.org - -FHDL is made of several elements, which are briefly explained below. They all can be imported directly from the ``migen`` module. - -Expressions -*********** - -Constants -========= - -The ``Constant`` object represents a constant, HDL-literal integer. It behaves like specifying integers and booleans but also supports slicing and can have a bit width or signedness different from what is implied by the value it represents. - -``True`` and ``False`` are interpreted as 1 and 0, respectively. - -Negative integers are explicitly supported. As with MyHDL [countin]_, arithmetic operations return the natural results. - -To lighten the syntax, assignments and operators automatically wrap Python integers and booleans into ``Constant``. Additionally, ``Constant`` is aliased to ``C``. The following are valid Migen statements: ``a.eq(0)``, ``a.eq(a + 1)``, ``a.eq(C(42)[0:1])``. - -.. [countin] http://www.jandecaluwe.com/hdldesign/counting.html - -Signal -====== - -The signal object represents a value that is expected to change in the circuit. It does exactly what Verilog's "wire" and "reg" and VHDL's "signal" do. - -The main point of the signal object is that it is identified by its Python ID (as returned by the :py:func:`id` function), and nothing else. It is the responsibility of the V*HDL back-end to establish an injective mapping between Python IDs and the V*HDL namespace. It should perform name mangling to ensure this. The consequence of this is that signal objects can safely become members of arbitrary Python classes, or be passed as parameters to functions or methods that generate logic involving them. - -The properties of a signal object are: - -* An integer or a (integer, boolean) pair that defines the number of bits and whether the bit of higher index of the signal is a sign bit (i.e. the signal is signed). The defaults are one bit and unsigned. Alternatively, the ``min`` and ``max`` parameters can be specified to define the range of the signal and determine its bit width and signedness. As with Python ranges, ``min`` is inclusive and defaults to 0, ``max`` is exclusive and defaults to 2. -* A name, used as a hint for the V*HDL back-end name mangler. -* The signal's reset value. It must be an integer, and defaults to 0. When the signal's value is modified with a synchronous statement, the reset value is the initialization value of the associated register. When the signal is assigned to in a conditional combinatorial statement (``If`` or ``Case``), the reset value is the value that the signal has when no condition that causes the signal to be driven is verified. This enforces the absence of latches in designs. If the signal is permanently driven using a combinatorial statement, the reset value has no effect. - -The sole purpose of the name property is to make the generated V*HDL code easier to understand and debug. From a purely functional point of view, it is perfectly OK to have several signals with the same name property. The back-end will generate a unique name for each object. If no name property is specified, Migen will analyze the code that created the signal object, and try to extract the variable or member name from there. For example, the following statements will create one or several signals named "bar": :: - - bar = Signal() - self.bar = Signal() - self.baz.bar = Signal() - bar = [Signal() for x in range(42)] - -In case of conflicts, Migen tries first to resolve the situation by prefixing the identifiers with names from the class and module hierarchy that created them. If the conflict persists (which can be the case if two signal objects are created with the same name in the same context), it will ultimately add number suffixes. - -Operators -========= - -Operators are represented by the ``_Operator`` object, which generally should not be used directly. Instead, most FHDL objects overload the usual Python logic and arithmetic operators, which allows a much lighter syntax to be used. For example, the expression: :: - - a * b + c - -is equivalent to:: - - _Operator("+", [_Operator("*", [a, b]), c]) - -Slices -====== - -Likewise, slices are represented by the ``_Slice`` object, which often should not be used in favor of the Python slice operation [x:y]. Implicit indices using the forms [x], [x:] and [:y] are supported. Beware! Slices work like Python slices, not like VHDL or Verilog slices. The first bound is the index of the LSB and is inclusive. The second bound is the index of MSB and is exclusive. In V*HDL, bounds are MSB:LSB and both are inclusive. - -Concatenations -============== - -Concatenations are done using the ``Cat`` object. To make the syntax lighter, its constructor takes a variable number of arguments, which are the signals to be concatenated together (you can use the Python "*" operator to pass a list instead). -To be consistent with slices, the first signal is connected to the bits with the lowest indices in the result. This is the opposite of the way the "{}" construct works in Verilog. - -Replications -============ - -The ``Replicate`` object represents the equivalent of {count{expression}} in Verilog. - -Statements -********** - -Assignment -========== - -Assignments are represented with the ``_Assign`` object. Since using it directly would result in a cluttered syntax, the preferred technique for assignments is to use the ``eq()`` method provided by objects that can have a value assigned to them. They are signals, and their combinations with the slice and concatenation operators. -As an example, the statement: :: - - a[0].eq(b) - -is equivalent to: :: - - _Assign(_Slice(a, 0, 1), b) - -If -== - -The ``If`` object takes a first parameter which must be an expression (combination of the ``Constant``, ``Signal``, ``_Operator``, ``_Slice``, etc. objects) representing the condition, then a variable number of parameters representing the statements (``_Assign``, ``If``, ``Case``, etc. objects) to be executed when the condition is verified. - -The ``If`` object defines a ``Else()`` method, which when called defines the statements to be executed when the condition is not true. Those statements are passed as parameters to the variadic method. - -For convenience, there is also a ``Elif()`` method. - -Example: :: - - If(tx_count16 == 0, - tx_bitcount.eq(tx_bitcount + 1), - If(tx_bitcount == 8, - self.tx.eq(1) - ).Elif(tx_bitcount == 9, - self.tx.eq(1), - tx_busy.eq(0) - ).Else( - self.tx.eq(tx_reg[0]), - tx_reg.eq(Cat(tx_reg[1:], 0)) - ) - ) - -Case -==== - -The ``Case`` object constructor takes as first parameter the expression to be tested, and a dictionary whose keys are the values to be matched, and values the statements to be executed in the case of a match. The special value ``"default"`` can be used as match value, which means the statements should be executed whenever there is no other match. - -Arrays -====== - -The ``Array`` object represents lists of other objects that can be indexed by FHDL expressions. It is explicitly possible to: - -* nest ``Array`` objects to create multidimensional tables. -* list any Python object in a ``Array`` as long as every expression appearing in a module ultimately evaluates to a ``Signal`` for all possible values of the indices. This allows the creation of lists of structured data. -* use expressions involving ``Array`` objects in both directions (assignment and reading). - -For example, this creates a 4x4 matrix of 1-bit signals: :: - - my_2d_array = Array(Array(Signal() for a in range(4)) for b in range(4)) - -You can then read the matrix with (``x`` and ``y`` being 2-bit signals): :: - - out.eq(my_2d_array[x][y]) - -and write it with: :: - - my_2d_array[x][y].eq(inp) - -Since they have no direct equivalent in Verilog, ``Array`` objects are lowered into multiplexers and conditional statements before the actual conversion takes place. Such lowering happens automatically without any user intervention. - -Specials -******** - -Tri-state I/O -============= - -A triplet (O, OE, I) of one-way signals defining a tri-state I/O port is represented by the ``TSTriple`` object. Such objects are only containers for signals that are intended to be later connected to a tri-state I/O buffer, and cannot be used as module specials. Such objects, however, should be kept in the design as long as possible as they allow the individual one-way signals to be manipulated in a non-ambiguous way. - -The object that can be used in as a module special is ``Tristate``, and it behaves exactly like an instance of a tri-state I/O buffer that would be defined as follows: :: - - Instance("Tristate", - io_target=target, - i_o=o, - i_oe=oe, - o_i=i - ) - -Signals ``target``, ``o`` and ``i`` can have any width, while ``oe`` is 1-bit wide. The ``target`` signal should go to a port and not be used elsewhere in the design. Like modern FPGA architectures, Migen does not support internal tri-states. - -A ``Tristate`` object can be created from a ``TSTriple`` object by calling the ``get_tristate`` method. - -By default, Migen emits technology-independent behavioral code for a tri-state buffer. If a specific code is needed, the tristate handler can be overriden using the appropriate parameter of the V*HDL conversion function. - -Instances -========= - -Instance objects represent the parametrized instantiation of a V*HDL module, and the connection of its ports to FHDL signals. They are useful in a number of cases: - -* Reusing legacy or third-party V*HDL code. -* Using special FPGA features (DCM, ICAP, ...). -* Implementing logic that cannot be expressed with FHDL (e.g. latches). -* Breaking down a Migen system into multiple sub-systems. - -The instance object constructor takes the type (i.e. name of the instantiated module) of the instance, then multiple parameters describing how to connect and parametrize the instance. - -These parameters can be: - -* ``Instance.Input``, ``Instance.Output`` or ``Instance.InOut`` to describe signal connections with the instance. The parameters are the name of the port at the instance, and the FHDL expression it should be connected to. -* ``Instance.Parameter`` sets a parameter (with a name and value) of the instance. -* ``Instance.ClockPort`` and ``Instance.ResetPort`` are used to connect clock and reset signals to the instance. The only mandatory parameter is the name of the port at the instance. Optionally, a clock domain name can be specified, and the ``invert`` option can be used to interface to those modules that require a 180-degree clock or a active-low reset. - -Memories -======== - -Memories (on-chip SRAM) are supported using a mechanism similar to instances. - -A memory object has the following parameters: - -* The width, which is the number of bits in each word. -* The depth, which represents the number of words in the memory. -* An optional list of integers used to initialize the memory. - -To access the memory in hardware, ports can be obtained by calling the ``get_port`` method. A port always has an address signal ``a`` and a data read signal ``dat_r``. Other signals may be available depending on the port's configuration. - -Options to ``get_port`` are: - -* ``write_capable`` (default: ``False``): if the port can be used to write to the memory. This creates an additional ``we`` signal. -* ``async_read`` (default: ``False``): whether reads are asychronous (combinatorial) or synchronous (registered). -* ``has_re`` (default: ``False``): adds a read clock-enable signal ``re`` (ignored for asychronous ports). -* ``we_granularity`` (default: ``0``): if non-zero, writes of less than a memory word can occur. The width of the ``we`` signal is increased to act as a selection signal for the sub-words. -* ``mode`` (default: ``WRITE_FIRST``, ignored for aynchronous ports). It can be: - - * ``READ_FIRST``: during a write, the previous value is read. - * ``WRITE_FIRST``: the written value is returned. - * ``NO_CHANGE``: the data read signal keeps its previous value on a write. - -* ``clock_domain`` (default: ``"sys"``): the clock domain used for reading and writing from this port. - -Migen generates behavioural V*HDL code that should be compatible with all simulators and, if the number of ports is <= 2, most FPGA synthesizers. If a specific code is needed, the memory handler can be overriden using the appropriate parameter of the V*HDL conversion function. - -Inline synthesis directives -=========================== - -Inline synthesis directives (pseudo-comments such as ``// synthesis attribute keep of clock_signal_name is true``) are supported using the ``SynthesisDirective`` object. Its constructor takes as parameters a string containing the body of the directive, and optional keyword parameters that are used to replace signal names similarly to the Python string method ``format``. The above example could be represented as follows: :: - - SynthesisDirective("attribute keep of {clksig} is true", clksig=clock_domain.clk) - -Modules -******* - -Modules play the same role as Verilog modules and VHDL entities. Similarly, they are organized in a tree structure. A FHDL module is a Python object that derives from the ``Module`` class. This class defines special attributes to be used by derived classes to describe their logic. They are explained below. - -Combinatorial statements -======================== - -A combinatorial statement is a statement that is executed whenever one of its inputs changes. - -Combinatorial statements are added to a module by using the ``comb`` special attribute. Like most module special attributes, it must be accessed using the ``+=`` incrementation operator, and either a single statement, a tuple of statements or a list of statements can appear on the right hand side. - -For example, the module below implements a OR gate: :: - - class ORGate(Module): - def __init__(self): - self.a = Signal() - self.b = Signal() - self.x = Signal() - - ### - - self.comb += x.eq(a | b) - -To improve code readability, it is recommended to place the interface of the module at the beginning of the ``__init__`` function, and separate it from the implementation using three hash signs. - -Synchronous statements -====================== - -A synchronous statements is a statement that is executed at each edge of some clock signal. - -They are added to a module by using the ``sync`` special attribute, which has the same properties as the ``comb`` attribute. - -The ``sync`` special attribute also has sub-attributes that correspond to abstract clock domains. For example, to add a statement to the clock domain named ``foo``, one would write ``self.sync.foo += statement``. The default clock domain is ``sys`` and writing ``self.sync += statement`` is equivalent to writing ``self.sync.sys += statement``. - -Submodules and specials -======================= - -Submodules and specials can be added by using the ``submodules`` and ``specials`` attributes respectively. This can be done in two ways: - -#. anonymously, by using the ``+=`` operator on the special attribute directly, e.g. ``self.submodules += some_other_module``. Like with the ``comb`` and ``sync`` attributes, a single module/special or a tuple or list can be specified. -#. by naming the submodule/special using a subattribute of the ``submodules`` or ``specials`` attribute, e.g. ``self.submodules.foo = module_foo``. The submodule/special is then accessible as an attribute of the object, e.g. ``self.foo`` (and not ``self.submodules.foo``). Only one submodule/special can be added at a time using this form. - -Clock domains -============= - -Specifying the implementation of a clock domain is done using the ``ClockDomain`` object. It contains the name of the clock domain, a clock signal that can be driven like any other signal in the design (for example, using a PLL instance), and optionally a reset signal. Clock domains without a reset signal are reset using e.g. ``initial`` statements in Verilog, which in many FPGA families initalize the registers during configuration. - -The name can be omitted if it can be extracted from the variable name. When using this automatic naming feature, prefixes ``_``, ``cd_`` and ``_cd_`` are removed. - -Clock domains are then added to a module using the ``clock_domains`` special attribute, which behaves exactly like ``submodules`` and ``specials``. - -Summary of special attributes -============================= - -.. table:: - - +--------------------------------------------+--------------------------------------------------------------+ - | Syntax | Action | - +============================================+==============================================================+ - | self.comb += stmt | Add combinatorial statement to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.comb += stmtA, stmtB | Add combinatorial statements A and B to current module. | - | | | - | self.comb += [stmtA, stmtB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.sync += stmt | Add synchronous statement to current module, in default | - | | clock domain sys. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.sync.foo += stmt | Add synchronous statement to current module, in clock domain | - | | foo. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.sync.foo += stmtA, stmtB | Add synchronous statements A and B to current module, in | - | | clock domain foo. | - | self.sync.foo += [stmtA, stmtB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.submodules += mod | Add anonymous submodule to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.submodules += modA, modB | Add anonymous submodules A and B to current module. | - | | | - | self.submodules += [modA, modB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.submodules.bar = mod | Add submodule named bar to current module. The submodule can | - | | then be accessed using self.bar. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.specials += spe | Add anonymous special to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.specials += speA, speB | Add anonymous specials A and B to current module. | - | | | - | self.specials += [speA, speB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.specials.bar = spe | Add special named bar to current module. The special can | - | | then be accessed using self.bar. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.clock_domains += cd | Add clock domain to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.clock_domains += cdA, cdB | Add clock domains A and B to current module. | - | | | - | self.clock_domains += [cdA, cdB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.clock_domains.pix = ClockDomain() | Create and add clock domain pix to current module. The clock | - | | domain name is pix in all cases. It can be accessed using | - | self.clock_domains._pix = ClockDomain() | self.pix, self._pix, self.cd_pix and self._cd_pix, | - | | respectively. | - | self.clock_domains.cd_pix = ClockDomain() | | - | | | - | self.clock_domains._cd_pix = ClockDomain() | | - +--------------------------------------------+--------------------------------------------------------------+ - -Clock domain management -======================= - -When a module has named submodules that define one or several clock domains with the same name, those clock domain names are prefixed with the name of each submodule plus an underscore. - -An example use case of this feature is a system with two independent video outputs. Each video output module is made of a clock generator module that defines a clock domain ``pix`` and drives the clock signal, plus a driver module that has synchronous statements and other elements in clock domain ``pix``. The designer of the video output module can simply use the clock domain name ``pix`` in that module. In the top-level system module, the video output submodules are named ``video0`` and ``video1``. Migen then automatically renames the ``pix`` clock domain of each module to ``video0_pix`` and ``video1_pix``. Note that happens only because the clock domain is defined (using ClockDomain objects), not simply referenced (using e.g. synchronous statements) in the video output modules. - -Clock domain name overlap is an error condition when any of the submodules that defines the clock domains is anonymous. - -Finalization mechanism -====================== - -Sometimes, it is desirable that some of a module logic be created only after the user has finished manipulating that module. For example, the FSM module supports that states be defined dynamically, and the width of the state signal can be known only after all states have been added. One solution is to declare the final number of states in the FSM constructor, but this is not user-friendly. A better solution is to automatically create the state signal just before the FSM module is converted to V*HDL. Migen supports this using the so-called finalization mechanism. - -Modules can overload a ``do_finalize`` method that can create logic and is called using the algorithm below: - -#. Finalization of the current module begins. -#. If the module has already been finalized (e.g. manually), the procedure stops here. -#. Submodules of the current module are recursively finalized. -#. ``do_finalize`` is called for the current module. -#. Any new submodules created by the current module's ``do_finalize`` are recursively finalized. - -Finalization is automatically invoked at V*HDL conversion and at simulation. It can be manually invoked for any module by calling its ``finalize`` method. - -The clock domain management mechanism explained above happens during finalization. - -Conversion for synthesis -************************ - -Any FHDL module can be converted into synthesizable Verilog HDL. This is accomplished by using the ``convert`` function in the ``verilog`` module. - -The ``migen.build`` component provides scripts to interface third-party FPGA tools (from Xilinx, Altera and Lattice) to Migen, and a database of boards for the easy deployment of designs. diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index 36f73aa3..00000000 --- a/doc/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -Migen manual -############ - -.. toctree:: - :maxdepth: 2 - - introduction - fhdl - simulation - synthesis - reference diff --git a/doc/introduction.rst b/doc/introduction.rst deleted file mode 100644 index bc24e336..00000000 --- a/doc/introduction.rst +++ /dev/null @@ -1,73 +0,0 @@ -Introduction -############ - -Migen is a Python-based tool that aims at automating further the VLSI design process. - -Migen makes it possible to apply modern software concepts such as object-oriented programming and metaprogramming to design hardware. This results in more elegant and easily maintained designs and reduces the incidence of human errors. - -.. _background: - -Background -********** - -Even though the Milkymist system-on-chip [mm]_ had many successes, it suffers from several limitations stemming from its implementation in manually written Verilog HDL: - -.. [mm] http://m-labs.hk - -#. The "event-driven" paradigm of today's dominant hardware descriptions languages (Verilog and VHDL, collectively referred to as "V*HDL" in the rest of this document) is often too general. Today's FPGA architectures are optimized for the implementation of fully synchronous circuits. This means that the bulk of the code for an efficient FPGA design falls into three categories: - - #. Combinatorial statements - #. Synchronous statements - #. Initialization of registers at reset - - V*HDL do not follow this organization. This means that a lot of repetitive manual coding is needed, which brings sources of human errors, petty issues, and confusion for beginners: - - #. wire vs. reg in Verilog - #. forgetting to initialize a register at reset - #. deciding whether a combinatorial statement must go into a process/always block or not - #. simulation mismatches with combinatorial processes/always blocks - #. and more... - - A little-known fact about FPGAs is that many of them have the ability to initialize their registers from the bitstream contents. This can be done in a portable and standard way using an "initial" block in Verilog, and by affecting a value at the signal declaration in VHDL. This renders an explicit reset signal unnecessary in practice in some cases, which opens the way for further design optimization. However, this form of initialization is entirely not synthesizable for ASIC targets, and it is not easy to switch between the two forms of reset using V*HDL. - -#. V*HDL support for composite types is very limited. Signals having a record type in VHDL are unidirectional, which makes them clumsy to use e.g. in bus interfaces. There is no record type support in Verilog, which means that a lot of copy-and-paste has to be done when forwarding grouped signals. - -#. V*HDL support for procedurally generated logic is extremely limited. The most advanced forms of procedural generation of synthesizable logic that V*HDL offers are CPP-style directives in Verilog, combinatorial functions, and ``generate`` statements. Nothing really fancy, and it shows. To give a few examples: - - #. Building highly flexible bus interconnect is not possible. Even arbitrating any given number of bus masters for commonplace protocols such as Wishbone is difficult with the tools that V*HDL puts at our disposal. - #. Building a memory infrastructure (including bus interconnect, bridges and caches) that can automatically adapt itself at compile-time to any word size of the SDRAM is clumsy and tedious. - #. Building register banks for control, status and interrupt management of cores can also largely benefit from automation. - #. Many hardware acceleration problems can fit into the dataflow programming model. Manual dataflow implementation in V*HDL has, again, a lot of redundancy and potential for human errors. See the Milkymist texture mapping unit [mthesis]_ [mxcell]_ for an example of this. The amount of detail to deal with manually also makes the design space exploration difficult, and therefore hinders the design of efficient architectures. - #. Pre-computation of values, such as filter coefficients for DSP or even simply trigonometric tables, must often be done using external tools whose results are copy-and-pasted (in the best case, automatically) into the V*HDL source. - -.. [mthesis] http://m-labs.hk/thesis/thesis.pdf -.. [mxcell] http://www.xilinx.com/publications/archives/xcell/Xcell77.pdf p30-35 - -Enter Migen, a Python toolbox for building complex digital hardware. We could have designed a brand new programming language, but that would have been reinventing the wheel instead of being able to benefit from Python's rich features and immense library. The price to pay is a slightly cluttered syntax at times when writing descriptions in FHDL, but we believe this is totally acceptable, particularly when compared to VHDL ;-) - -Migen is made up of several related components: - -#. the base language, FHDL -#. a library of small generic cores -#. a simulator -#. a build system - -Installing Migen -**************** - -Either run the ``setup.py`` installation script or simply set ``PYTHONPATH`` to the root of the source directory. - -If you wish to contribute patches, the suggest way to install is; - #. Clone from the git repository at http://github.com/m-labs/migen - #. Install using ``python3 ./setup.py develop --user`` - #. Edit the code in your git checkout. - -Alternative install methods -=========================== - - * Migen is available for the Anaconda Python distribution. The package can be found at at https://anaconda.org/m-labs/migen - * Migen can be referenced in a requirements.txt file (used for ``pip install -r requirements.txt``) via ``-e git+http://github.com/m-labs/migen.git#egg=migen``. See the pip documentation for more information. - -Feedback -******** -Feedback concerning Migen or this manual should be sent to the M-Labs developers' mailing list ``devel`` on lists.m-labs.hk. diff --git a/doc/migen_logo.png b/doc/migen_logo.png deleted file mode 100644 index 8c86fc04604c7c3113f61721b393a9a6d723701e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74931 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 TgR8Hhl^4&OoGUy-xb;5(+tqtZ diff --git a/doc/migen_logo.svg b/doc/migen_logo.svg deleted file mode 100644 index fdb855ec..00000000 --- a/doc/migen_logo.svg +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - migen - - - - diff --git a/doc/reference.rst b/doc/reference.rst deleted file mode 100644 index bec65ce8..00000000 --- a/doc/reference.rst +++ /dev/null @@ -1,37 +0,0 @@ -API reference -============= - -:mod:`fhdl.structure` module ----------------------------- - -.. automodule:: migen.fhdl.structure - :members: - :show-inheritance: - -:mod:`fhdl.bitcontainer` module -------------------------------- - -.. automodule:: migen.fhdl.bitcontainer - :members: - :show-inheritance: - -:mod:`genlib.fifo` module -------------------------- - -.. automodule:: migen.genlib.fifo - :members: - :show-inheritance: - -:mod:`genlib.coding` module ---------------------------- - -.. automodule:: migen.genlib.coding - :members: - :show-inheritance: - -:mod:`genlib.sort` module -------------------------- - -.. automodule:: migen.genlib.sort - :members: - :show-inheritance: diff --git a/doc/simulation.rst b/doc/simulation.rst deleted file mode 100644 index eff0ba5f..00000000 --- a/doc/simulation.rst +++ /dev/null @@ -1,6 +0,0 @@ -Simulating a Migen design -######################### - -Migen allows you to easily simulate your FHDL design and interface it with arbitrary Python code. The simulator is written in pure Python and interprets the FHDL structure directly without using an external Verilog simulator. - -[To be rewritten] diff --git a/doc/synthesis.rst b/doc/synthesis.rst deleted file mode 100644 index a5b99502..00000000 --- a/doc/synthesis.rst +++ /dev/null @@ -1,4 +0,0 @@ -Synthesizing a Migen design -########################### - -[To be written] diff --git a/examples/basic/arrays.py b/examples/basic/arrays.py deleted file mode 100644 index 0753107c..00000000 --- a/examples/basic/arrays.py +++ /dev/null @@ -1,28 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self): - dx = 2 - dy = 2 - - x = Signal(max=dx) - y = Signal(max=dy) - out = Signal() - - my_2d_array = Array(Array(Signal() for a in range(dx)) for b in range(dy)) - self.comb += out.eq(my_2d_array[x][y]) - - we = Signal() - inp = Signal() - self.sync += If(we, - my_2d_array[x][y].eq(inp) - ) - - ina = Array(Signal() for a in range(dx)) - outa = Array(Signal() for a in range(dy)) - self.specials += Instance("test", o_O=outa[y], i_I=ina[x]) - -if __name__ == "__main__": - print(verilog.convert(Example())) diff --git a/examples/basic/fsm.py b/examples/basic/fsm.py deleted file mode 100644 index ca235bfe..00000000 --- a/examples/basic/fsm.py +++ /dev/null @@ -1,31 +0,0 @@ -from migen import * -from migen.fhdl import verilog - -class Example(Module): - def __init__(self): - self.s = Signal() - self.counter = Signal(8) - x = Array(Signal(name="a") for i in range(7)) - - myfsm = FSM() - self.submodules += myfsm - - myfsm.act("FOO", - self.s.eq(1), - NextState("BAR") - ) - myfsm.act("BAR", - self.s.eq(0), - NextValue(self.counter, self.counter + 1), - NextValue(x[self.counter], 89), - NextState("FOO") - ) - - self.be = myfsm.before_entering("FOO") - self.ae = myfsm.after_entering("FOO") - self.bl = myfsm.before_leaving("FOO") - self.al = myfsm.after_leaving("FOO") - -if __name__ == "__main__": - example = Example() - print(verilog.convert(example, {example.s, example.counter, example.be, example.ae, example.bl, example.al})) diff --git a/examples/basic/graycounter.py b/examples/basic/graycounter.py deleted file mode 100644 index 28865a24..00000000 --- a/examples/basic/graycounter.py +++ /dev/null @@ -1,18 +0,0 @@ -from random import Random - -from migen import * -from migen.genlib.cdc import GrayCounter - - -def tb(dut): - prng = Random(7345) - for i in range(35): - print("{0:0{1}b} CE={2} bin={3}".format((yield dut.q), - len(dut.q), (yield dut.ce), (yield dut.q_binary))) - yield dut.ce.eq(prng.getrandbits(1)) - yield - - -if __name__ == "__main__": - dut = GrayCounter(3) - run_simulation(dut, tb(dut), vcd_name="graycounter.vcd") diff --git a/examples/basic/instance.py b/examples/basic/instance.py deleted file mode 100644 index fcabecc1..00000000 --- a/examples/basic/instance.py +++ /dev/null @@ -1,68 +0,0 @@ -import subprocess - -from migen import * -from migen.fhdl.verilog import convert - - -# Create a parent module with two instances of a child module. -# Bind input ports to first module and output ports to second, -# and create internal signals to connect the first module to the -# second. -class ParentModule(Module): - def __init__(self): - self.inputs = [Signal(x+1, name="input{}".format(x)) for x in range(4)] - self.trans = [Signal(x+1) for x in range(4)] - self.outputs = [Signal(x+1, name="output{}".format(x)) for x in range(4)] - self.io = set(self.inputs) | set(self.outputs) - i = Instance("ChildModule", - i_master_clk=ClockSignal(), - i_master_rst=ResetSignal(), - i_input0=self.inputs[0], - i_input1=self.inputs[1], - i_input2=self.inputs[2], - i_input3=self.inputs[3], - o_output0=self.trans[0], - o_output1=self.trans[1], - o_output2=self.trans[2], - o_output3=self.trans[3] - ) - j = Instance("ChildModule", - i_master_clk=ClockSignal(), - i_master_rst=ResetSignal(), - i_input0=self.trans[0], - i_input1=self.trans[1], - i_input2=self.trans[2], - i_input3=self.trans[3], - o_output0=self.outputs[0], - o_output1=self.outputs[1], - o_output2=self.outputs[2], - o_output3=self.outputs[3] - ) - self.specials += i, j - - -class ChildModule(Module): - def __init__(self): - self.inputs = [Signal(x+1, name_override="input{}".format(x)) for x in range(4)] - self.outputs = [Signal(x+1, name_override="output{}".format(x)) for x in range(4)] - self.io = set() - for x in range(4): - self.sync.master += self.outputs[x].eq(self.inputs[x]) - self.io = self.io.union(self.inputs) - self.io = self.io.union(self.outputs) - - -# Generate RTL for the parent module and the submodule, run through -# icarus for a syntax check -def test_instance_module(): - sub = ChildModule() - convert(sub, sub.io, name="ChildModule").write("ChildModule.v") - - im = ParentModule() - convert(im, im.io, name="ParentModule").write("ParentModule.v") - - subprocess.check_call(["iverilog", "-W", "all", - "ParentModule.v", "ChildModule.v"]) - -if __name__ == "__main__": - test_instance_module() diff --git a/examples/basic/local_cd.py b/examples/basic/local_cd.py deleted file mode 100644 index dc055060..00000000 --- a/examples/basic/local_cd.py +++ /dev/null @@ -1,19 +0,0 @@ -from migen import * -from migen.fhdl import verilog -from migen.genlib.divider import Divider - - -class CDM(Module): - def __init__(self): - self.submodules.divider = Divider(5) - self.clock_domains.cd_sys = ClockDomain(reset_less=True) - - -class MultiMod(Module): - def __init__(self): - self.submodules.foo = CDM() - self.submodules.bar = CDM() - -if __name__ == "__main__": - mm = MultiMod() - print(verilog.convert(mm, {mm.foo.cd_sys.clk, mm.bar.cd_sys.clk})) diff --git a/examples/basic/memory.py b/examples/basic/memory.py deleted file mode 100644 index 6b9c1f2c..00000000 --- a/examples/basic/memory.py +++ /dev/null @@ -1,17 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self): - self.specials.mem = Memory(32, 100, init=[5, 18, 32]) - p1 = self.mem.get_port(write_capable=True, we_granularity=8) - p2 = self.mem.get_port(has_re=True, clock_domain="rd") - self.specials += p1, p2 - self.ios = {p1.adr, p1.dat_r, p1.we, p1.dat_w, - p2.adr, p2.dat_r, p2.re} - - -if __name__ == "__main__": - example = Example() - print(verilog.convert(example, example.ios)) diff --git a/examples/basic/namer.py b/examples/basic/namer.py deleted file mode 100644 index 0c30c814..00000000 --- a/examples/basic/namer.py +++ /dev/null @@ -1,44 +0,0 @@ -from migen import * -from migen.fhdl import verilog - -from functools import reduce -from operator import or_ - - -def gen_list(n): - s = [Signal() for i in range(n)] - return s - - -def gen_2list(n): - s = [Signal(2) for i in range(n)] - return s - - -class Foo: - def __init__(self): - la = gen_list(3) - lb = gen_2list(2) - self.sigs = la + lb - - -class Bar: - def __init__(self): - self.sigs = gen_list(2) - - -class Example(Module): - def __init__(self): - a = [Bar() for x in range(3)] - b = [Foo() for x in range(3)] - c = b - b = [Bar() for x in range(2)] - - output = Signal() - allsigs = [] - for lst in [a, b, c]: - for obj in lst: - allsigs.extend(obj.sigs) - self.comb += output.eq(reduce(or_, allsigs)) - -print(verilog.convert(Example())) diff --git a/examples/basic/psync.py b/examples/basic/psync.py deleted file mode 100644 index 034ca69f..00000000 --- a/examples/basic/psync.py +++ /dev/null @@ -1,23 +0,0 @@ -from migen import * -from migen.fhdl.specials import SynthesisDirective -from migen.fhdl import verilog -from migen.genlib.cdc import * - - -class XilinxMultiRegImpl(MultiRegImpl): - def __init__(self, *args, **kwargs): - MultiRegImpl.__init__(self, *args, **kwargs) - self.specials += set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r) - for r in self.regs) - - -class XilinxMultiReg: - @staticmethod - def lower(dr): - return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) - - -if __name__ == "__main__": - ps = PulseSynchronizer("from", "to") - v = verilog.convert(ps, {ps.i, ps.o}, special_overrides={MultiReg: XilinxMultiReg}) - print(v) diff --git a/examples/basic/record.py b/examples/basic/record.py deleted file mode 100644 index 59e72774..00000000 --- a/examples/basic/record.py +++ /dev/null @@ -1,26 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -L = [ - ("position", [ - ("x", 10, DIR_M_TO_S), - ("y", 10, DIR_M_TO_S), - ]), - ("color", 32, DIR_M_TO_S), - ("stb", 1, DIR_M_TO_S), - ("ack", 1, DIR_S_TO_M) -] - - -class Test(Module): - def __init__(self): - master = Record(L) - slave = Record(L) - self.comb += master.connect(slave) - - -if __name__ == "__main__": - print(verilog.convert(Test())) - print(layout_len(L)) - print(layout_partial(L, "position/x", "color")) diff --git a/examples/basic/reslice.py b/examples/basic/reslice.py deleted file mode 100644 index c5fb502a..00000000 --- a/examples/basic/reslice.py +++ /dev/null @@ -1,19 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self): - a = Signal(3) - b = Signal(4) - c = Signal(5) - d = Signal(7) - s1 = c[:3][:2] - s2 = Cat(a, b)[:6] - s3 = Cat(s1, s2)[-5:] - self.comb += s3.eq(0) - self.comb += d.eq(Cat(d[::-1], Cat(s1[:1], s3[-4:])[:3])) - - -if __name__ == "__main__": - print(verilog.convert(Example())) diff --git a/examples/basic/tristate.py b/examples/basic/tristate.py deleted file mode 100644 index 51afa033..00000000 --- a/examples/basic/tristate.py +++ /dev/null @@ -1,13 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self, n=6): - self.pad = Signal(n) - self.t = TSTriple(n) - self.specials += self.t.get_tristate(self.pad) - -if __name__ == "__main__": - e = Example() - print(verilog.convert(e, ios={e.pad, e.t.o, e.t.oe, e.t.i})) diff --git a/examples/basic/two_dividers.py b/examples/basic/two_dividers.py deleted file mode 100644 index 6869d548..00000000 --- a/examples/basic/two_dividers.py +++ /dev/null @@ -1,19 +0,0 @@ -from migen import * -from migen.fhdl import verilog -from migen.genlib import divider - - -@ResetInserter() -@CEInserter() -class Example(Module): - def __init__(self, width): - d1 = divider.Divider(width) - d2 = divider.Divider(width) - self.submodules += d1, d2 - self.ios = { - d1.ready_o, d1.quotient_o, d1.remainder_o, d1.start_i, d1.dividend_i, d1.divisor_i, - d2.ready_o, d2.quotient_o, d2.remainder_o, d2.start_i, d2.dividend_i, d2.divisor_i} - -if __name__ == "__main__": - example = Example(16) - print(verilog.convert(example, example.ios | {example.ce, example.reset})) diff --git a/examples/sim/basic1.py b/examples/sim/basic1.py deleted file mode 100644 index 62afd21b..00000000 --- a/examples/sim/basic1.py +++ /dev/null @@ -1,29 +0,0 @@ -from migen import * - - -# Our simple counter, which increments at every cycle. -class Counter(Module): - def __init__(self): - self.count = Signal(4) - - # At each cycle, increase the value of the count signal. - # We do it with convertible/synthesizable FHDL code. - self.sync += self.count.eq(self.count + 1) - - -# Simply read the count signal and print it. -# The output is: -# Count: 0 -# Count: 1 -# Count: 2 -# ... -def counter_test(dut): - for i in range(20): - print((yield dut.count)) # read and print - yield # next clock cycle - # simulation ends with this generator - - -if __name__ == "__main__": - dut = Counter() - run_simulation(dut, counter_test(dut), vcd_name="basic1.vcd") diff --git a/examples/sim/basic2.py b/examples/sim/basic2.py deleted file mode 100644 index 45bc676f..00000000 --- a/examples/sim/basic2.py +++ /dev/null @@ -1,37 +0,0 @@ -from migen import * - - -# A slightly more elaborate counter. -# Has a clock enable (CE) signal, counts on more bits -# and resets with a negative number. -class Counter(Module): - def __init__(self): - self.ce = Signal() - # Demonstrate negative numbers and signals larger than 32 bits. - self.count = Signal((37, True), reset=-5) - - self.sync += If(self.ce, self.count.eq(self.count + 1)) - - -def counter_test(dut): - for cycle in range(20): - # Only assert CE every second cycle. - # => each counter value is held for two cycles. - if cycle % 2: - yield dut.ce.eq(0) # This is how you write to a signal. - else: - yield dut.ce.eq(1) - print("Cycle: {} Count: {}".format(cycle, (yield dut.count))) - yield - -# Output is: -# Cycle: 0 Count: -5 -# Cycle: 1 Count: -5 -# Cycle: 2 Count: -4 -# Cycle: 3 Count: -4 -# Cycle: 4 Count: -3 -# ... - -if __name__ == "__main__": - dut = Counter() - run_simulation(dut, counter_test(dut), vcd_name="basic2.vcd") diff --git a/examples/sim/fir.py b/examples/sim/fir.py deleted file mode 100644 index 67a78bc7..00000000 --- a/examples/sim/fir.py +++ /dev/null @@ -1,67 +0,0 @@ -from functools import reduce -from operator import add - -from math import cos, pi -from scipy import signal -import matplotlib.pyplot as plt - -from migen import * -from migen.fhdl import verilog - - -# A synthesizable FIR filter. -class FIR(Module): - def __init__(self, coef, wsize=16): - self.coef = coef - self.wsize = wsize - self.i = Signal((self.wsize, True)) - self.o = Signal((self.wsize, True)) - - ### - - muls = [] - src = self.i - for c in self.coef: - sreg = Signal((self.wsize, True)) - self.sync += sreg.eq(src) - src = sreg - c_fp = int(c*2**(self.wsize - 1)) - muls.append(c_fp*sreg) - sum_full = Signal((2*self.wsize-1, True)) - self.sync += sum_full.eq(reduce(add, muls)) - self.comb += self.o.eq(sum_full >> self.wsize-1) - - -# A test bench for our FIR filter. -# Generates a sine wave at the input and records the output. -def fir_tb(dut, frequency, inputs, outputs): - f = 2**(dut.wsize - 1) - for cycle in range(200): - v = 0.1*cos(2*pi*frequency*cycle) - yield dut.i.eq(int(f*v)) - inputs.append(v) - outputs.append((yield dut.o)/f) - yield - - -if __name__ == "__main__": - # Compute filter coefficients with SciPy. - coef = signal.remez(30, [0, 0.1, 0.2, 0.4, 0.45, 0.5], [0, 1, 0]) - - # Simulate for different frequencies and concatenate - # the results. - in_signals = [] - out_signals = [] - for frequency in [0.05, 0.1, 0.25]: - dut = FIR(coef) - tb = fir_tb(dut, frequency, in_signals, out_signals) - run_simulation(dut, tb) - - # Plot data from the input and output waveforms. - plt.plot(in_signals) - plt.plot(out_signals) - plt.show() - - # Print the Verilog source for the filter. - fir = FIR(coef) - print(verilog.convert(fir, ios={fir.i, fir.o})) diff --git a/examples/sim/memory.py b/examples/sim/memory.py deleted file mode 100644 index 51a0c329..00000000 --- a/examples/sim/memory.py +++ /dev/null @@ -1,26 +0,0 @@ -from migen import * - - -class Mem(Module): - def __init__(self): - # Initialize the beginning of the memory with integers - # from 0 to 19. - self.specials.mem = Memory(16, 2**12, init=list(range(20))) - - -def memory_test(dut): - # write (only first 5 values) - for i in range(5): - yield dut.mem[i].eq(42 + i) - # remember: values are written after the tick, and read before the tick. - # wait one tick for the memory to update. - yield - # read what we have written, plus some initialization data - for i in range(10): - value = yield dut.mem[i] - print(value) - - -if __name__ == "__main__": - dut = Mem() - run_simulation(dut, memory_test(dut)) diff --git a/litex/gen/migen/build/__init__.py b/litex/__init__.py similarity index 100% rename from litex/gen/migen/build/__init__.py rename to litex/__init__.py diff --git a/litex/gen/migen/build/platforms/__init__.py b/litex/boards/__init__.py similarity index 100% rename from litex/gen/migen/build/platforms/__init__.py rename to litex/boards/__init__.py diff --git a/litex/gen/migen/fhdl/__init__.py b/litex/boards/platforms/__init__.py similarity index 100% rename from litex/gen/migen/fhdl/__init__.py rename to litex/boards/platforms/__init__.py diff --git a/litex/gen/migen/build/platforms/de0nano.py b/litex/boards/platforms/de0nano.py similarity index 95% rename from litex/gen/migen/build/platforms/de0nano.py rename to litex/boards/platforms/de0nano.py index 4ef34daf..0997f1be 100644 --- a/litex/gen/migen/build/platforms/de0nano.py +++ b/litex/boards/platforms/de0nano.py @@ -1,9 +1,9 @@ # This file is Copyright (c) 2013 Florent Kermarrec # License: BSD -from migen.build.generic_platform import * -from migen.build.altera import AlteraPlatform -from migen.build.altera.programmer import USBBlaster +from litex.build.generic_platform import * +from litex.build.altera import AlteraPlatform +from litex.build.altera.programmer import USBBlaster _io = [ diff --git a/migen/build/platforms/kc705.py b/litex/boards/platforms/kc705.py similarity index 98% rename from migen/build/platforms/kc705.py rename to litex/boards/platforms/kc705.py index eb51ab33..fc86272f 100644 --- a/migen/build/platforms/kc705.py +++ b/litex/boards/platforms/kc705.py @@ -1,6 +1,6 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT -from migen.build.xilinx.ise import XilinxISEToolchain +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT +from litex.build.xilinx.ise import XilinxISEToolchain _io = [ diff --git a/migen/build/platforms/minispartan6.py b/litex/boards/platforms/minispartan6.py similarity index 96% rename from migen/build/platforms/minispartan6.py rename to litex/boards/platforms/minispartan6.py index c46fa29c..681786f8 100644 --- a/migen/build/platforms/minispartan6.py +++ b/litex/boards/platforms/minispartan6.py @@ -1,9 +1,9 @@ # This file is Copyright (c) 2015 Matt O'Gorman # License: BSD -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg, FpgaProg +from litex.build.generic_platform import * +from litex.build.xilinx import XilinxPlatform +from litex.build.xilinx.programmer import XC3SProg, FpgaProg _io = [ diff --git a/migen/build/platforms/sim.py b/litex/boards/platforms/sim.py similarity index 92% rename from migen/build/platforms/sim.py rename to litex/boards/platforms/sim.py index 0e4a40d1..8b099184 100644 --- a/migen/build/platforms/sim.py +++ b/litex/boards/platforms/sim.py @@ -1,5 +1,5 @@ -from migen.build.generic_platform import * -from migen.build.sim import SimPlatform +from litex.build.generic_platform import * +from litex.build.sim import SimPlatform class SimPins(Pins): diff --git a/migen/build/platforms/versa.py b/litex/boards/platforms/versa.py similarity index 95% rename from migen/build/platforms/versa.py rename to litex/boards/platforms/versa.py index dc8dd53d..e1a0cf5f 100644 --- a/migen/build/platforms/versa.py +++ b/litex/boards/platforms/versa.py @@ -1,9 +1,9 @@ # This file is Copyright (c) 2013 Florent Kermarrec # License: BSD -from migen.build.generic_platform import * -from migen.build.lattice import LatticePlatform -from migen.build.lattice.programmer import LatticeProgrammer +from litex.build.generic_platform import * +from litex.build.lattice import LatticePlatform +from litex.build.lattice.programmer import LatticeProgrammer _io = [ diff --git a/litex/gen/migen/genlib/__init__.py b/litex/boards/targets/__init__.py similarity index 100% rename from litex/gen/migen/genlib/__init__.py rename to litex/boards/targets/__init__.py diff --git a/litex/soc/misoc/targets/de0nano.py b/litex/boards/targets/de0nano.py similarity index 91% rename from litex/soc/misoc/targets/de0nano.py rename to litex/boards/targets/de0nano.py index f73a6d77..790c69fe 100644 --- a/litex/soc/misoc/targets/de0nano.py +++ b/litex/boards/targets/de0nano.py @@ -2,13 +2,13 @@ import argparse -from migen import * -from migen.build.platforms import de0nano +from litex.gen import * +from litex.boards.platforms import de0nano -from misoc.cores.sdram_settings import IS42S16160 -from misoc.cores.sdram_phy import GENSDRPHY -from misoc.integration.soc_sdram import * -from misoc.integration.builder import * +from litex.soc.cores.sdram.settings import IS42S16160 +from litex.soc.cores.sdram.phy import GENSDRPHY +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * class _PLL(Module): @@ -101,7 +101,7 @@ class BaseSoC(SoCSDRAM): sdram_module.geom_settings, sdram_module.timing_settings) def main(): - parser = argparse.ArgumentParser(description="MiSoC port to the Altera DE0 Nano") + parser = argparse.ArgumentParser(description="LiteX SoC port to the Altera DE0 Nano") builder_args(parser) soc_sdram_args(parser) args = parser.parse_args() diff --git a/litex/soc/misoc/targets/kc705.py b/litex/boards/targets/kc705.py similarity index 90% rename from litex/soc/misoc/targets/kc705.py rename to litex/boards/targets/kc705.py index 1af1ad66..b63a9fc8 100644 --- a/litex/soc/misoc/targets/kc705.py +++ b/litex/boards/targets/kc705.py @@ -2,19 +2,19 @@ import argparse -from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.build.platforms import kc705 +from litex.gen import * +from litex.gen.genlib.resetsync import AsyncResetSynchronizer +from litex.boards.platforms import kc705 -from misoc.cores.sdram_settings import MT8JTF12864 -from misoc.cores.sdram_phy import k7ddrphy -from misoc.cores import spi_flash -from misoc.cores.liteeth_mini.phy import LiteEthPHY -from misoc.cores.liteeth_mini.mac import LiteEthMAC -from misoc.integration.soc_core import mem_decoder -from misoc.integration.soc_sdram import * -from misoc.integration.builder import * +from litex.soc.cores.sdram.settings import MT8JTF12864 +from litex.soc.cores.sdram.phy import k7ddrphy +from litex.soc.cores.flash import spi_flash +from litex.soc.integration.soc_core import mem_decoder +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * +from liteeth.phy import LiteEthPHY +from liteeth.core.mac import LiteEthMAC class _CRG(Module): @@ -150,7 +150,7 @@ def soc_kc705_argdict(args): def main(): - parser = argparse.ArgumentParser(description="MiSoC port to the KC705") + parser = argparse.ArgumentParser(description="LiteX SoC port to the KC705") builder_args(parser) soc_kc705_args(parser) parser.add_argument("--with-ethernet", action="store_true", diff --git a/litex/soc/misoc/targets/minispartan6.py b/litex/boards/targets/minispartan6.py similarity index 90% rename from litex/soc/misoc/targets/minispartan6.py rename to litex/boards/targets/minispartan6.py index 72f5e0c8..7fead695 100644 --- a/litex/soc/misoc/targets/minispartan6.py +++ b/litex/boards/targets/minispartan6.py @@ -3,14 +3,14 @@ import argparse from fractions import Fraction -from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.build.platforms import minispartan6 +from litex.gen import * +from litex.gen.genlib.resetsync import AsyncResetSynchronizer +from litex.boards.platforms import minispartan6 -from misoc.cores.sdram_settings import AS4C16M16 -from misoc.cores.sdram_phy import GENSDRPHY -from misoc.integration.soc_sdram import * -from misoc.integration.builder import * +from litex.soc.cores.sdram.settings import AS4C16M16 +from litex.soc.cores.sdram.phy import GENSDRPHY +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * class _CRG(Module): @@ -82,7 +82,7 @@ class BaseSoC(SoCSDRAM): def main(): - parser = argparse.ArgumentParser(description="MiSoC port to the MiniSpartan6") + parser = argparse.ArgumentParser(description="LiteX SoC port to the MiniSpartan6") builder_args(parser) soc_sdram_args(parser) args = parser.parse_args() diff --git a/litex/soc/misoc/targets/papilio_pro.py b/litex/boards/targets/papilio_pro.py similarity index 90% rename from litex/soc/misoc/targets/papilio_pro.py rename to litex/boards/targets/papilio_pro.py index 9710553f..9e7a86e1 100644 --- a/litex/soc/misoc/targets/papilio_pro.py +++ b/litex/boards/targets/papilio_pro.py @@ -3,15 +3,15 @@ import argparse from fractions import Fraction -from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.build.platforms import papilio_pro +from litex.gen import * +from litex.gen.genlib.resetsync import AsyncResetSynchronizer +from litex.boards.platforms import papilio_pro -from misoc.cores.sdram_settings import MT48LC4M16 -from misoc.cores.sdram_phy import GENSDRPHY -from misoc.cores import spi_flash -from misoc.integration.soc_sdram import * -from misoc.integration.builder import * +from litex.soc.cores.sdram.settings import MT48LC4M16 +from litex.soc.cores.sdram.phy import GENSDRPHY +from litex.soc.cores.flash import spi_flash +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * class _CRG(Module): @@ -94,7 +94,7 @@ class BaseSoC(SoCSDRAM): def main(): - parser = argparse.ArgumentParser(description="MiSoC port to the Papilio Pro") + parser = argparse.ArgumentParser(description="LiteX SoC port to the Papilio Pro") builder_args(parser) soc_sdram_args(parser) args = parser.parse_args() diff --git a/litex/soc/misoc/targets/pipistrello.py b/litex/boards/targets/pipistrello.py similarity index 93% rename from litex/soc/misoc/targets/pipistrello.py rename to litex/boards/targets/pipistrello.py index b78ded2d..6ec6fc4b 100644 --- a/litex/soc/misoc/targets/pipistrello.py +++ b/litex/boards/targets/pipistrello.py @@ -3,15 +3,15 @@ import argparse from fractions import Fraction -from migen import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.build.platforms import pipistrello +from litex.gen import * +from litex.gen.genlib.resetsync import AsyncResetSynchronizer +from litex.boards.platforms import pipistrello -from misoc.cores.sdram_settings import MT46H32M16 -from misoc.cores.sdram_phy import S6HalfRateDDRPHY -from misoc.cores import spi_flash -from misoc.integration.soc_sdram import * -from misoc.integration.builder import * +from litex.soc.cores.sdram_settings import MT46H32M16 +from litex.soc.cores.sdram_phy import S6HalfRateDDRPHY +from litex.soc.cores.flash import spi_flash +from litex.soc.integration.soc_sdram import * +from litex.soc.integration.builder import * class _CRG(Module): @@ -136,7 +136,7 @@ soc_pipistrello_argdict = soc_sdram_argdict def main(): - parser = argparse.ArgumentParser(description="MiSoC port to the Pipistrello") + parser = argparse.ArgumentParser(description="LiteX SoC port to the Pipistrello") builder_args(parser) soc_pipistrello_args(parser) args = parser.parse_args() diff --git a/litex/soc/misoc/targets/simple.py b/litex/boards/targets/simple.py similarity index 83% rename from litex/soc/misoc/targets/simple.py rename to litex/boards/targets/simple.py index e6d89128..8ac27505 100644 --- a/litex/soc/misoc/targets/simple.py +++ b/litex/boards/targets/simple.py @@ -3,13 +3,14 @@ import argparse import importlib -from migen import * -from migen.genlib.io import CRG +from litex.gen import * +from litex.gen.genlib.io import CRG -from misoc.cores.liteeth_mini.phy import LiteEthPHY -from misoc.cores.liteeth_mini.mac import LiteEthMAC -from misoc.integration.soc_core import * -from misoc.integration.builder import * +from litex.soc.integration.soc_core import * +from litex.soc.integration.builder import * + +from liteeth.phy import LiteEthPHY +from liteeth.core.mac import LiteEthMAC class BaseSoC(SoCCore): @@ -52,13 +53,13 @@ class MiniSoC(BaseSoC): def main(): - parser = argparse.ArgumentParser(description="Generic MiSoC port") + parser = argparse.ArgumentParser(description="Generic LiteX SoC") builder_args(parser) soc_core_args(parser) parser.add_argument("--with-ethernet", action="store_true", help="enable Ethernet support") parser.add_argument("platform", - help="module name of the Migen platform to build for") + help="module name of the platform to build for") args = parser.parse_args() platform_module = importlib.import_module(args.platform) diff --git a/litex/gen/migen/test/__init__.py b/litex/build/__init__.py similarity index 100% rename from litex/gen/migen/test/__init__.py rename to litex/build/__init__.py diff --git a/litex/build/altera/__init__.py b/litex/build/altera/__init__.py new file mode 100644 index 00000000..64eadc0d --- /dev/null +++ b/litex/build/altera/__init__.py @@ -0,0 +1,2 @@ +from litex.build.altera.platform import AlteraPlatform +from litex.build.altera.programmer import USBBlaster diff --git a/litex/gen/migen/build/altera/common.py b/litex/build/altera/common.py similarity index 86% rename from litex/gen/migen/build/altera/common.py rename to litex/build/altera/common.py index fafb4983..07b6ef76 100644 --- a/litex/gen/migen/build/altera/common.py +++ b/litex/build/altera/common.py @@ -1,6 +1,6 @@ -from migen.fhdl.module import Module -from migen.fhdl.specials import Instance -from migen.genlib.io import DifferentialInput, DifferentialOutput +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.specials import Instance +from litex.gen.genlib.io import DifferentialInput, DifferentialOutput class AlteraDifferentialInputImpl(Module): diff --git a/migen/build/altera/platform.py b/litex/build/altera/platform.py similarity index 89% rename from migen/build/altera/platform.py rename to litex/build/altera/platform.py index 43841fa7..bccab35d 100644 --- a/migen/build/altera/platform.py +++ b/litex/build/altera/platform.py @@ -1,5 +1,5 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.altera import common, quartus +from litex.build.generic_platform import GenericPlatform +from litex.build.altera import common, quartus class AlteraPlatform(GenericPlatform): diff --git a/migen/build/altera/programmer.py b/litex/build/altera/programmer.py similarity index 85% rename from migen/build/altera/programmer.py rename to litex/build/altera/programmer.py index 369f7db1..93561d22 100644 --- a/migen/build/altera/programmer.py +++ b/litex/build/altera/programmer.py @@ -1,6 +1,6 @@ import subprocess -from migen.build.generic_programmer import GenericProgrammer +from litex.build.generic_programmer import GenericProgrammer class USBBlaster(GenericProgrammer): diff --git a/litex/gen/migen/build/altera/quartus.py b/litex/build/altera/quartus.py similarity index 96% rename from litex/gen/migen/build/altera/quartus.py rename to litex/build/altera/quartus.py index 99f6e978..d5eda886 100644 --- a/litex/gen/migen/build/altera/quartus.py +++ b/litex/build/altera/quartus.py @@ -4,10 +4,10 @@ import os import subprocess -from migen.fhdl.structure import _Fragment +from litex.gen.fhdl.structure import _Fragment -from migen.build.generic_platform import Pins, IOStandard, Misc -from migen.build import tools +from litex.build.generic_platform import Pins, IOStandard, Misc +from litex.build import tools def _format_constraint(c, signame, fmt_r): @@ -92,7 +92,7 @@ def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name): def _run_quartus(build_name, quartus_path): - build_script_contents = """# Autogenerated by Migen + build_script_contents = """# Autogenerated by LiteX set -e diff --git a/migen/build/generic_platform.py b/litex/build/generic_platform.py similarity index 98% rename from migen/build/generic_platform.py rename to litex/build/generic_platform.py index 5163d922..f6320acc 100644 --- a/migen/build/generic_platform.py +++ b/litex/build/generic_platform.py @@ -1,10 +1,10 @@ import os -from migen.fhdl.structure import Signal -from migen.genlib.record import Record -from migen.genlib.io import CRG -from migen.fhdl import verilog, edif -from migen.build import tools +from litex.gen.fhdl.structure import Signal +from litex.gen.genlib.record import Record +from litex.gen.genlib.io import CRG +from litex.gen.fhdl import verilog, edif +from litex.build import tools class ConstraintError(Exception): diff --git a/litex/gen/migen/build/generic_programmer.py b/litex/build/generic_programmer.py similarity index 86% rename from litex/gen/migen/build/generic_programmer.py rename to litex/build/generic_programmer.py index 82a1ebe0..b9540415 100644 --- a/litex/gen/migen/build/generic_programmer.py +++ b/litex/build/generic_programmer.py @@ -5,8 +5,7 @@ class GenericProgrammer: def __init__(self, flash_proxy_basename=None): self.flash_proxy_basename = flash_proxy_basename self.flash_proxy_dirs = [ - "~/.migen", "/usr/local/share/migen", "/usr/share/migen", - "~/.mlabs", "/usr/local/share/mlabs", "/usr/share/mlabs"] + "~/.litex", "/usr/local/share/litex", "/usr/share/litex"] def set_flash_proxy_dir(self, flash_proxy_dir): if flash_proxy_dir is not None: diff --git a/litex/build/lattice/__init__.py b/litex/build/lattice/__init__.py new file mode 100644 index 00000000..6b356c72 --- /dev/null +++ b/litex/build/lattice/__init__.py @@ -0,0 +1,2 @@ +from litex.build.lattice.platform import LatticePlatform +from litex.build.lattice.programmer import LatticeProgrammer diff --git a/litex/gen/migen/build/lattice/common.py b/litex/build/lattice/common.py similarity index 84% rename from litex/gen/migen/build/lattice/common.py rename to litex/build/lattice/common.py index c25e8b90..52cf28d9 100644 --- a/litex/gen/migen/build/lattice/common.py +++ b/litex/build/lattice/common.py @@ -1,7 +1,7 @@ -from migen.fhdl.module import Module -from migen.fhdl.specials import Instance -from migen.genlib.io import * -from migen.genlib.resetsync import AsyncResetSynchronizer +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.specials import Instance +from litex.gen.genlib.io import * +from litex.gen.genlib.resetsync import AsyncResetSynchronizer class LatticeAsyncResetSynchronizerImpl(Module): diff --git a/migen/build/lattice/diamond.py b/litex/build/lattice/diamond.py similarity index 94% rename from migen/build/lattice/diamond.py rename to litex/build/lattice/diamond.py index 1334040b..cd169fdb 100644 --- a/migen/build/lattice/diamond.py +++ b/litex/build/lattice/diamond.py @@ -6,11 +6,11 @@ import sys import subprocess import shutil -from migen.fhdl.structure import _Fragment +from litex.gen.fhdl.structure import _Fragment -from migen.build.generic_platform import * -from migen.build import tools -from migen.build.lattice import common +from litex.build.generic_platform import * +from litex.build import tools +from litex.build.lattice import common def _format_constraint(c): @@ -61,7 +61,7 @@ def _build_files(device, sources, vincpaths, build_name): def _run_diamond(build_name, source, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": - build_script_contents = "REM Autogenerated by Migen\n" + build_script_contents = "REM Autogenerated by LiteX\n" build_script_contents = "pnmainc " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".bat" tools.write_to_file(build_script_file, build_script_contents) diff --git a/migen/build/lattice/platform.py b/litex/build/lattice/platform.py similarity index 89% rename from migen/build/lattice/platform.py rename to litex/build/lattice/platform.py index 73742231..d7170636 100644 --- a/migen/build/lattice/platform.py +++ b/litex/build/lattice/platform.py @@ -1,5 +1,5 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.lattice import common, diamond +from litex.build.generic_platform import GenericPlatform +from litex.build.lattice import common, diamond class LatticePlatform(GenericPlatform): diff --git a/litex/gen/migen/build/lattice/programmer.py b/litex/build/lattice/programmer.py similarity index 94% rename from litex/gen/migen/build/lattice/programmer.py rename to litex/build/lattice/programmer.py index cc3c50bd..94726d22 100644 --- a/litex/gen/migen/build/lattice/programmer.py +++ b/litex/build/lattice/programmer.py @@ -1,8 +1,8 @@ import os import subprocess -from migen.build.generic_programmer import GenericProgrammer -from migen.build import tools +from litex.build.generic_programmer import GenericProgrammer +from litex.build import tools # XXX Lattice programmer need an .xcf file, will need clean up and support for more parameters diff --git a/litex/gen/migen/build/openocd.py b/litex/build/openocd.py similarity index 93% rename from litex/gen/migen/build/openocd.py rename to litex/build/openocd.py index aec29980..da83ba5c 100644 --- a/litex/gen/migen/build/openocd.py +++ b/litex/build/openocd.py @@ -1,6 +1,6 @@ import subprocess -from migen.build.generic_programmer import GenericProgrammer +from litex.build.generic_programmer import GenericProgrammer class OpenOCD(GenericProgrammer): diff --git a/litex/build/sim/__init__.py b/litex/build/sim/__init__.py new file mode 100644 index 00000000..5457c4fa --- /dev/null +++ b/litex/build/sim/__init__.py @@ -0,0 +1 @@ +from litex.build.sim.platform import SimPlatform diff --git a/litex/gen/migen/build/sim/common.py b/litex/build/sim/common.py similarity index 100% rename from litex/gen/migen/build/sim/common.py rename to litex/build/sim/common.py diff --git a/litex/gen/migen/build/sim/dut_tb.cpp b/litex/build/sim/dut_tb.cpp similarity index 100% rename from litex/gen/migen/build/sim/dut_tb.cpp rename to litex/build/sim/dut_tb.cpp diff --git a/litex/gen/migen/build/sim/platform.py b/litex/build/sim/platform.py similarity index 86% rename from litex/gen/migen/build/sim/platform.py rename to litex/build/sim/platform.py index 0c5e17d2..a86d1d08 100644 --- a/litex/gen/migen/build/sim/platform.py +++ b/litex/build/sim/platform.py @@ -1,5 +1,5 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.sim import common, verilator +from litex.build.generic_platform import GenericPlatform +from litex.build.sim import common, verilator class SimPlatform(GenericPlatform): diff --git a/litex/gen/migen/build/sim/verilator.py b/litex/build/sim/verilator.py similarity index 96% rename from litex/gen/migen/build/sim/verilator.py rename to litex/build/sim/verilator.py index 4e635528..658392d7 100644 --- a/litex/gen/migen/build/sim/verilator.py +++ b/litex/build/sim/verilator.py @@ -4,9 +4,9 @@ import os import subprocess -from migen.fhdl.structure import _Fragment -from migen.build import tools -from migen.build.generic_platform import * +from litex.gen.fhdl.structure import _Fragment +from litex.build import tools +from litex.build.generic_platform import * def _build_tb(platform, vns, serial, template): @@ -86,7 +86,7 @@ def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbo for path in include_paths: include += "-I"+path+" " - build_script_contents = """# Autogenerated by Migen + build_script_contents = """# Autogenerated by LiteX rm -rf obj_dir/ verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include} make -j -C obj_dir/ -f Vdut.mk Vdut diff --git a/litex/gen/migen/build/tools.py b/litex/build/tools.py similarity index 100% rename from litex/gen/migen/build/tools.py rename to litex/build/tools.py diff --git a/litex/build/xilinx/__init__.py b/litex/build/xilinx/__init__.py new file mode 100644 index 00000000..53e6e840 --- /dev/null +++ b/litex/build/xilinx/__init__.py @@ -0,0 +1,2 @@ +from litex.build.xilinx.platform import XilinxPlatform +from litex.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept diff --git a/litex/gen/migen/build/xilinx/common.py b/litex/build/xilinx/common.py similarity index 91% rename from litex/gen/migen/build/xilinx/common.py rename to litex/build/xilinx/common.py index 52f8ca97..69c15384 100644 --- a/litex/gen/migen/build/xilinx/common.py +++ b/litex/build/xilinx/common.py @@ -2,15 +2,15 @@ import os import sys from distutils.version import StrictVersion -from migen.fhdl.structure import * -from migen.fhdl.specials import Instance -from migen.fhdl.module import Module -from migen.fhdl.specials import SynthesisDirective -from migen.genlib.cdc import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.io import * - -from migen.build import tools +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.specials import Instance +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.specials import SynthesisDirective +from litex.gen.genlib.cdc import * +from litex.gen.genlib.resetsync import AsyncResetSynchronizer +from litex.gen.genlib.io import * + +from litex.build import tools def settings(path, ver=None, sub=None): diff --git a/litex/gen/migen/build/xilinx/ise.py b/litex/build/xilinx/ise.py similarity index 96% rename from litex/gen/migen/build/xilinx/ise.py rename to litex/build/xilinx/ise.py index 72e82a90..8efa5d7a 100644 --- a/litex/gen/migen/build/xilinx/ise.py +++ b/litex/build/xilinx/ise.py @@ -2,10 +2,10 @@ import os import subprocess import sys -from migen.fhdl.structure import _Fragment -from migen.build.generic_platform import * -from migen.build import tools -from migen.build.xilinx import common +from litex.gen.fhdl.structure import _Fragment +from litex.build.generic_platform import * +from litex.build import tools +from litex.build.xilinx import common def _format_constraint(c): @@ -87,12 +87,12 @@ def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt, source_cmd = "call " script_ext = ".bat" shell = ["cmd", "/c"] - build_script_contents = "@echo off\nrem Autogenerated by Migen\n" + build_script_contents = "@echo off\nrem Autogenerated by LiteX\n" else: source_cmd = "source " script_ext = ".sh" shell = ["bash"] - build_script_contents = "# Autogenerated by Migen\nset -e\n" + build_script_contents = "# Autogenerated by LiteX\nset -e\n" if source: settings = common.settings(ise_path, ver, "ISE_DS") build_script_contents += source_cmd + settings + "\n" diff --git a/litex/gen/migen/build/xilinx/platform.py b/litex/build/xilinx/platform.py similarity index 91% rename from litex/gen/migen/build/xilinx/platform.py rename to litex/build/xilinx/platform.py index d4ca4b18..ffe12fb6 100644 --- a/litex/gen/migen/build/xilinx/platform.py +++ b/litex/build/xilinx/platform.py @@ -1,5 +1,5 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.xilinx import common, vivado, ise +from litex.build.generic_platform import GenericPlatform +from litex.build.xilinx import common, vivado, ise class XilinxPlatform(GenericPlatform): diff --git a/litex/gen/migen/build/xilinx/programmer.py b/litex/build/xilinx/programmer.py similarity index 98% rename from litex/gen/migen/build/xilinx/programmer.py rename to litex/build/xilinx/programmer.py index 8291465a..47b76fce 100644 --- a/litex/gen/migen/build/xilinx/programmer.py +++ b/litex/build/xilinx/programmer.py @@ -2,8 +2,8 @@ import os import sys import subprocess -from migen.build.generic_programmer import GenericProgrammer -from migen.build.xilinx import common +from litex.build.generic_programmer import GenericProgrammer +from litex.build.xilinx import common def _run_urjtag(cmds): diff --git a/migen/build/xilinx/vivado.py b/litex/build/xilinx/vivado.py similarity index 95% rename from migen/build/xilinx/vivado.py rename to litex/build/xilinx/vivado.py index c1a54a41..18474d3d 100644 --- a/migen/build/xilinx/vivado.py +++ b/litex/build/xilinx/vivado.py @@ -5,10 +5,10 @@ import os import subprocess import sys -from migen.fhdl.structure import _Fragment -from migen.build.generic_platform import * -from migen.build import tools -from migen.build.xilinx import common +from litex.gen.fhdl.structure import _Fragment +from litex.build.generic_platform import * +from litex.build import tools +from litex.build.xilinx import common def _format_constraint(c): @@ -52,13 +52,13 @@ def _build_xdc(named_sc, named_pc): def _run_vivado(build_name, vivado_path, source, ver=None): if sys.platform == "win32" or sys.platform == "cygwin": - build_script_contents = "REM Autogenerated by Migen\n" + build_script_contents = "REM Autogenerated by LiteX\n" build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" build_script_file = "build_" + build_name + ".bat" tools.write_to_file(build_script_file, build_script_contents) r = subprocess.call([build_script_file]) else: - build_script_contents = "# Autogenerated by Migen\nset -e\n" + build_script_contents = "# Autogenerated by LiteX\nset -e\n" settings = common.settings(vivado_path, ver) build_script_contents += "source " + settings + "\n" build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" diff --git a/litex/gen/.gitignore b/litex/gen/.gitignore deleted file mode 100644 index 3fa21c42..00000000 --- a/litex/gen/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -__pycache__ -*.pyc -*.egg-info/ -vpi/*.o -vpi/migensim.vpi -examples/*.vcd -doc/_build diff --git a/litex/gen/.travis.yml b/litex/gen/.travis.yml deleted file mode 100644 index 315850e3..00000000 --- a/litex/gen/.travis.yml +++ /dev/null @@ -1,52 +0,0 @@ -language: python -python: - - "3.5" - -env: - global: - - PATH=$HOME/miniconda/bin:$PATH - -before_install: - # Install Miniconda - - wget https://raw.githubusercontent.com/m-labs/artiq/master/.travis/get-anaconda.sh - - chmod +x get-anaconda.sh - - ./get-anaconda.sh - - source $HOME/miniconda/bin/activate py35 - - conda install anaconda-client numpydoc -install: - # Install iverilog package. - # - "sudo add-apt-repository -y ppa:mithro/iverilog-backport" - # - "sudo apt-get update" - # - "sudo apt-get install iverilog" - # - "iverilog -v; true" - # Build the vpi module. - # - "(cd vpi; make; sudo make install)" - # Install verilator package - - "sudo apt-get install verilator" - - "verilator --version; true" - # Build and install Migen conda package - # workaround for https://github.com/conda/conda-build/issues/466 - - "mkdir -p /home/travis/miniconda/conda-bld/linux-64" - - "conda index /home/travis/miniconda/conda-bld/linux-64" - - "conda build --python 3.5 conda/migen" - - "conda install $(conda build --output --python 3.5 conda/migen)" - -script: - # Run tests - - "python setup.py test" - # Generate HTML documentation - - "make -C doc html" - -after_success: - # Upload Migen conda package to binstar - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda login --hostname $(hostname) --username $binstar_login --password $binstar_password; fi - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda upload --user $binstar_login --channel dev --force $HOME/miniconda/conda-bld/noarch/migen-*.tar.bz2; fi - -notifications: - email: false - irc: - channels: - - chat.freenode.net#m-labs - template: - - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}" - - "Build details : %{build_url}" diff --git a/litex/gen/LICENSE b/litex/gen/LICENSE deleted file mode 100644 index 4f290601..00000000 --- a/litex/gen/LICENSE +++ /dev/null @@ -1,31 +0,0 @@ -Unless otherwise noted, Migen is copyright (C) 2011-2013 Sebastien Bourdeauducq. -The simulation extension (as mentioned in the comments at the beginning of the -corresponding source files) is copyright (C) 2012 Vermeer Manufacturing Co. All -rights reserved. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -Other authors retain ownership of their contributions. If a submission can -reasonably be considered independently copyrightable, it's yours and we -encourage you to claim it with appropriate copyright notices. This submission -then falls under the "otherwise noted" category. All submissions are strongly -encouraged to use the two-clause BSD license reproduced above. diff --git a/LICENSE b/litex/gen/MIGEN_LICENSE similarity index 100% rename from LICENSE rename to litex/gen/MIGEN_LICENSE diff --git a/litex/gen/README.rst b/litex/gen/README.rst deleted file mode 100644 index 39f8e96a..00000000 --- a/litex/gen/README.rst +++ /dev/null @@ -1,82 +0,0 @@ -### Migen (Milkymist generator) - -[![Build Status](https://travis-ci.org/m-labs/migen.svg)]( -https://travis-ci.org/m-labs/migen) - -#### A Python toolbox for building complex digital hardware - -Despite being faster than schematics entry, hardware design with Verilog and -VHDL remains tedious and inefficient for several reasons. The event-driven -model introduces issues and manual coding that are unnecessary for synchronous -circuits, which represent the lion's share of today's logic designs. Counter- -intuitive arithmetic rules result in steeper learning curves and provide a -fertile ground for subtle bugs in designs. Finally, support for procedural -generation of logic (metaprogramming) through "generate" statements is very -limited and restricts the ways code can be made generic, reused and organized. - -To address those issues, we have developed the **Migen FHDL** library that -replaces the event-driven paradigm with the notions of combinatorial and -synchronous statements, has arithmetic rules that make integers always behave -like mathematical integers, and most importantly allows the design's logic to -be constructed by a Python program. This last point enables hardware designers -to take advantage of the richness of the Python language - object oriented -programming, function parameters, generators, operator overloading, libraries, -etc. - to build well organized, reusable and elegant designs. - -Other Migen libraries are built on FHDL and provide various tools such as a -system-on-chip interconnect infrastructure, a dataflow programming system, a -more traditional high-level synthesizer that compiles Python routines into -state machines with datapaths, and a simulator that allows test benches to be -written in Python. - -See the doc/ folder for more technical information. - -Migen is designed for Python 3.3. Note that Migen is **not** spelled MiGen. - -#### Quick Links - -Code repository: -https://github.com/m-labs/migen - -System-on-chip design based on Migen: -https://github.com/m-labs/misoc - -Online documentation: -http://m-labs.hk/gateware.html - -#### Quick intro - -```python -from migen import * -from migen.build.platforms import m1 -plat = m1.Platform() -led = plat.request("user_led") -m = Module() -counter = Signal(26) -m.comb += led.eq(counter[25]) -m.sync += counter.eq(counter + 1) -plat.build_cmdline(m) -``` - -#### License - -Migen is released under the very permissive two-clause BSD license. Under the -terms of this license, you are authorized to use Migen 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 Migen -* put the Migen logo (doc/migen_logo.svg) on the page of a product using it, - with a link to http://m-labs.hk -* cite Migen 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 Migen. 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 (#m-labs on Freenode) beforehand. - -See LICENSE file for full copyright and license info. You can contact us on the -public mailing list devel [AT] lists.m-labs.hk. - - "Electricity! It's like magic!" diff --git a/litex/gen/__init__.py b/litex/gen/__init__.py new file mode 100644 index 00000000..264a79e2 --- /dev/null +++ b/litex/gen/__init__.py @@ -0,0 +1,10 @@ +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import * +from litex.gen.fhdl.specials import * +from litex.gen.fhdl.bitcontainer import * +from litex.gen.fhdl.decorators import * + +from litex.gen.sim import * + +from litex.gen.genlib.record import * +from litex.gen.genlib.fsm import * diff --git a/litex/gen/conda/migen/bld.bat b/litex/gen/conda/migen/bld.bat deleted file mode 100644 index 39b5e1fe..00000000 --- a/litex/gen/conda/migen/bld.bat +++ /dev/null @@ -1 +0,0 @@ -%PYTHON% setup.py install diff --git a/litex/gen/conda/migen/meta.yaml b/litex/gen/conda/migen/meta.yaml deleted file mode 100644 index 1cf9baee..00000000 --- a/litex/gen/conda/migen/meta.yaml +++ /dev/null @@ -1,28 +0,0 @@ -package: - name: migen - version: {{ environ.get("GIT_DESCRIBE_TAG", "") }} - -source: - git_url: https://github.com/m-labs/migen - git_tag: master - -build: - noarch_python: true - number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }} - string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }} - script: $PYTHON setup.py install - -requirements: - build: - - python 3.5.* - run: - - python 3.5.* - -test: - imports: - - migen - -about: - home: http://m-labs.hk/gateware.html - license: 3-clause BSD - summary: 'A Python toolbox for building complex digital hardware' diff --git a/litex/gen/doc/Makefile b/litex/gen/doc/Makefile deleted file mode 100644 index d6a5924b..00000000 --- a/litex/gen/doc/Makefile +++ /dev/null @@ -1,130 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = _build - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - -rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/Migen.qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/Migen.qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/Migen" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/Migen" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - make -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." diff --git a/litex/gen/doc/_static/.keep_me b/litex/gen/doc/_static/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/litex/gen/doc/_templates/.keep_me b/litex/gen/doc/_templates/.keep_me deleted file mode 100644 index e69de29b..00000000 diff --git a/litex/gen/doc/conf.py b/litex/gen/doc/conf.py deleted file mode 100644 index f134ce9b..00000000 --- a/litex/gen/doc/conf.py +++ /dev/null @@ -1,223 +0,0 @@ -# -*- coding: utf-8 -*- -# -# Migen documentation build configuration file, created by -# sphinx-quickstart on Fri Mar 9 14:11:54 2012. -# -# This file is execfile()d with the current directory set to its containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -#sys.path.insert(0, os.path.abspath('.')) - -# -- General configuration ----------------------------------------------------- - -# If your documentation needs a minimal Sphinx version, state it here. -#needs_sphinx = '1.0' - -# Add any Sphinx extension module names here, as strings. They can be extensions -# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = [ - 'sphinx.ext.pngmath', - 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.autosummary', - 'numpydoc', # to preprocess docstrings - ] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# The suffix of source filenames. -source_suffix = '.rst' - -# The encoding of source files. -#source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = 'index' - -# General information about the project. -project = u'Migen' -copyright = u'2011-2015, M-Labs Limited' - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. -# -# The short X.Y version. -version = '1.0' -# The full version, including alpha/beta/rc tags. -release = '1.0' - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -#language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -#today = '' -# Else, today_fmt is used as the format for a strftime call. -#today_fmt = '%B %d, %Y' - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ['_build'] - -# The reST default role (used for this markup: `text`) to use for all documents. -#default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -#add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -#add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -#show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = 'sphinx' - -# A list of ignored prefixes for module index sorting. -modindex_common_prefix = ['migen.'] - -numpydoc_show_class_members = False - -# -- Options for HTML output --------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -html_theme = 'alabaster' - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -#html_theme_options = {} - -# Add any paths that contain custom themes here, relative to this directory. -#html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -#html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -#html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -#html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -#html_favicon = None - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -#html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -#html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -#html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -#html_additional_pages = {} - -# If false, no module index is generated. -#html_domain_indices = True - -# If false, no index is generated. -#html_use_index = True - -# If true, the index is split into individual pages for each letter. -#html_split_index = False - -# If true, links to the reST sources are added to the pages. -#html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -#html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -#html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -#html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -#html_file_suffix = None - -# Output file base name for HTML help builder. -htmlhelp_basename = 'Migendoc' - -html_use_modindex = False - -# -- Options for LaTeX output -------------------------------------------------- - -# The paper size ('letter' or 'a4'). -#latex_paper_size = 'letter' - -# The font size ('10pt', '11pt' or '12pt'). -#latex_font_size = '10pt' - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, author, documentclass [howto/manual]). -latex_documents = [ - ('index', 'Migen.tex', u'Migen manual', - u'Sebastien Bourdeauducq', 'manual'), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -latex_logo = "migen_logo.png" - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -#latex_use_parts = False - -# If true, show page references after internal links. -#latex_show_pagerefs = False - -# If true, show URL addresses after external links. -#latex_show_urls = False - -# Additional stuff for the LaTeX preamble. -latex_preamble = '\setcounter{tocdepth}{3}' - -# Documents to append as an appendix to all manuals. -#latex_appendices = [] - -# If false, no module index is generated. -#latex_domain_indices = True - -latex_use_modindex = False - -# -- Options for manual page output -------------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ('index', 'migen', u'Migen manual', - [u'Sebastien Bourdeauducq'], 1) -] diff --git a/litex/gen/doc/fhdl.rst b/litex/gen/doc/fhdl.rst deleted file mode 100644 index b6225605..00000000 --- a/litex/gen/doc/fhdl.rst +++ /dev/null @@ -1,362 +0,0 @@ -The FHDL domain-specific language -################################# - -The Fragmented Hardware Description Language (FHDL) is the basis of Migen. It consists of a formal system to describe signals, and combinatorial and synchronous statements operating on them. The formal system itself is low level and close to the synthesizable subset of Verilog, and we then rely on Python algorithms to build complex structures by combining FHDL elements. -The FHDL module also contains a back-end to produce synthesizable Verilog, and some structure analysis and manipulation functionality. - -FHDL differs from MyHDL [myhdl]_ in fundamental ways. MyHDL follows the event-driven paradigm of traditional HDLs (see :ref:`background`) while FHDL separates the code into combinatorial statements, synchronous statements, and reset values. In MyHDL, the logic is described directly in the Python AST. The converter to Verilog or VHDL then examines the Python AST and recognizes a subset of Python that it translates into V*HDL statements. This seriously impedes the capability of MyHDL to generate logic procedurally. With FHDL, you manipulate a custom AST from Python, and you can more easily design algorithms that operate on it. - -.. [myhdl] http://www.myhdl.org - -FHDL is made of several elements, which are briefly explained below. They all can be imported directly from the ``migen`` module. - -Expressions -*********** - -Constants -========= - -The ``Constant`` object represents a constant, HDL-literal integer. It behaves like specifying integers and booleans but also supports slicing and can have a bit width or signedness different from what is implied by the value it represents. - -``True`` and ``False`` are interpreted as 1 and 0, respectively. - -Negative integers are explicitly supported. As with MyHDL [countin]_, arithmetic operations return the natural results. - -To lighten the syntax, assignments and operators automatically wrap Python integers and booleans into ``Constant``. Additionally, ``Constant`` is aliased to ``C``. The following are valid Migen statements: ``a.eq(0)``, ``a.eq(a + 1)``, ``a.eq(C(42)[0:1])``. - -.. [countin] http://www.jandecaluwe.com/hdldesign/counting.html - -Signal -====== - -The signal object represents a value that is expected to change in the circuit. It does exactly what Verilog's "wire" and "reg" and VHDL's "signal" do. - -The main point of the signal object is that it is identified by its Python ID (as returned by the :py:func:`id` function), and nothing else. It is the responsibility of the V*HDL back-end to establish an injective mapping between Python IDs and the V*HDL namespace. It should perform name mangling to ensure this. The consequence of this is that signal objects can safely become members of arbitrary Python classes, or be passed as parameters to functions or methods that generate logic involving them. - -The properties of a signal object are: - -* An integer or a (integer, boolean) pair that defines the number of bits and whether the bit of higher index of the signal is a sign bit (i.e. the signal is signed). The defaults are one bit and unsigned. Alternatively, the ``min`` and ``max`` parameters can be specified to define the range of the signal and determine its bit width and signedness. As with Python ranges, ``min`` is inclusive and defaults to 0, ``max`` is exclusive and defaults to 2. -* A name, used as a hint for the V*HDL back-end name mangler. -* The signal's reset value. It must be an integer, and defaults to 0. When the signal's value is modified with a synchronous statement, the reset value is the initialization value of the associated register. When the signal is assigned to in a conditional combinatorial statement (``If`` or ``Case``), the reset value is the value that the signal has when no condition that causes the signal to be driven is verified. This enforces the absence of latches in designs. If the signal is permanently driven using a combinatorial statement, the reset value has no effect. - -The sole purpose of the name property is to make the generated V*HDL code easier to understand and debug. From a purely functional point of view, it is perfectly OK to have several signals with the same name property. The back-end will generate a unique name for each object. If no name property is specified, Migen will analyze the code that created the signal object, and try to extract the variable or member name from there. For example, the following statements will create one or several signals named "bar": :: - - bar = Signal() - self.bar = Signal() - self.baz.bar = Signal() - bar = [Signal() for x in range(42)] - -In case of conflicts, Migen tries first to resolve the situation by prefixing the identifiers with names from the class and module hierarchy that created them. If the conflict persists (which can be the case if two signal objects are created with the same name in the same context), it will ultimately add number suffixes. - -Operators -========= - -Operators are represented by the ``_Operator`` object, which generally should not be used directly. Instead, most FHDL objects overload the usual Python logic and arithmetic operators, which allows a much lighter syntax to be used. For example, the expression: :: - - a * b + c - -is equivalent to:: - - _Operator("+", [_Operator("*", [a, b]), c]) - -Slices -====== - -Likewise, slices are represented by the ``_Slice`` object, which often should not be used in favor of the Python slice operation [x:y]. Implicit indices using the forms [x], [x:] and [:y] are supported. Beware! Slices work like Python slices, not like VHDL or Verilog slices. The first bound is the index of the LSB and is inclusive. The second bound is the index of MSB and is exclusive. In V*HDL, bounds are MSB:LSB and both are inclusive. - -Concatenations -============== - -Concatenations are done using the ``Cat`` object. To make the syntax lighter, its constructor takes a variable number of arguments, which are the signals to be concatenated together (you can use the Python "*" operator to pass a list instead). -To be consistent with slices, the first signal is connected to the bits with the lowest indices in the result. This is the opposite of the way the "{}" construct works in Verilog. - -Replications -============ - -The ``Replicate`` object represents the equivalent of {count{expression}} in Verilog. - -Statements -********** - -Assignment -========== - -Assignments are represented with the ``_Assign`` object. Since using it directly would result in a cluttered syntax, the preferred technique for assignments is to use the ``eq()`` method provided by objects that can have a value assigned to them. They are signals, and their combinations with the slice and concatenation operators. -As an example, the statement: :: - - a[0].eq(b) - -is equivalent to: :: - - _Assign(_Slice(a, 0, 1), b) - -If -== - -The ``If`` object takes a first parameter which must be an expression (combination of the ``Constant``, ``Signal``, ``_Operator``, ``_Slice``, etc. objects) representing the condition, then a variable number of parameters representing the statements (``_Assign``, ``If``, ``Case``, etc. objects) to be executed when the condition is verified. - -The ``If`` object defines a ``Else()`` method, which when called defines the statements to be executed when the condition is not true. Those statements are passed as parameters to the variadic method. - -For convenience, there is also a ``Elif()`` method. - -Example: :: - - If(tx_count16 == 0, - tx_bitcount.eq(tx_bitcount + 1), - If(tx_bitcount == 8, - self.tx.eq(1) - ).Elif(tx_bitcount == 9, - self.tx.eq(1), - tx_busy.eq(0) - ).Else( - self.tx.eq(tx_reg[0]), - tx_reg.eq(Cat(tx_reg[1:], 0)) - ) - ) - -Case -==== - -The ``Case`` object constructor takes as first parameter the expression to be tested, and a dictionary whose keys are the values to be matched, and values the statements to be executed in the case of a match. The special value ``"default"`` can be used as match value, which means the statements should be executed whenever there is no other match. - -Arrays -====== - -The ``Array`` object represents lists of other objects that can be indexed by FHDL expressions. It is explicitly possible to: - -* nest ``Array`` objects to create multidimensional tables. -* list any Python object in a ``Array`` as long as every expression appearing in a module ultimately evaluates to a ``Signal`` for all possible values of the indices. This allows the creation of lists of structured data. -* use expressions involving ``Array`` objects in both directions (assignment and reading). - -For example, this creates a 4x4 matrix of 1-bit signals: :: - - my_2d_array = Array(Array(Signal() for a in range(4)) for b in range(4)) - -You can then read the matrix with (``x`` and ``y`` being 2-bit signals): :: - - out.eq(my_2d_array[x][y]) - -and write it with: :: - - my_2d_array[x][y].eq(inp) - -Since they have no direct equivalent in Verilog, ``Array`` objects are lowered into multiplexers and conditional statements before the actual conversion takes place. Such lowering happens automatically without any user intervention. - -Specials -******** - -Tri-state I/O -============= - -A triplet (O, OE, I) of one-way signals defining a tri-state I/O port is represented by the ``TSTriple`` object. Such objects are only containers for signals that are intended to be later connected to a tri-state I/O buffer, and cannot be used as module specials. Such objects, however, should be kept in the design as long as possible as they allow the individual one-way signals to be manipulated in a non-ambiguous way. - -The object that can be used in as a module special is ``Tristate``, and it behaves exactly like an instance of a tri-state I/O buffer that would be defined as follows: :: - - Instance("Tristate", - io_target=target, - i_o=o, - i_oe=oe, - o_i=i - ) - -Signals ``target``, ``o`` and ``i`` can have any width, while ``oe`` is 1-bit wide. The ``target`` signal should go to a port and not be used elsewhere in the design. Like modern FPGA architectures, Migen does not support internal tri-states. - -A ``Tristate`` object can be created from a ``TSTriple`` object by calling the ``get_tristate`` method. - -By default, Migen emits technology-independent behavioral code for a tri-state buffer. If a specific code is needed, the tristate handler can be overriden using the appropriate parameter of the V*HDL conversion function. - -Instances -========= - -Instance objects represent the parametrized instantiation of a V*HDL module, and the connection of its ports to FHDL signals. They are useful in a number of cases: - -* Reusing legacy or third-party V*HDL code. -* Using special FPGA features (DCM, ICAP, ...). -* Implementing logic that cannot be expressed with FHDL (e.g. latches). -* Breaking down a Migen system into multiple sub-systems. - -The instance object constructor takes the type (i.e. name of the instantiated module) of the instance, then multiple parameters describing how to connect and parametrize the instance. - -These parameters can be: - -* ``Instance.Input``, ``Instance.Output`` or ``Instance.InOut`` to describe signal connections with the instance. The parameters are the name of the port at the instance, and the FHDL expression it should be connected to. -* ``Instance.Parameter`` sets a parameter (with a name and value) of the instance. -* ``Instance.ClockPort`` and ``Instance.ResetPort`` are used to connect clock and reset signals to the instance. The only mandatory parameter is the name of the port at the instance. Optionally, a clock domain name can be specified, and the ``invert`` option can be used to interface to those modules that require a 180-degree clock or a active-low reset. - -Memories -======== - -Memories (on-chip SRAM) are supported using a mechanism similar to instances. - -A memory object has the following parameters: - -* The width, which is the number of bits in each word. -* The depth, which represents the number of words in the memory. -* An optional list of integers used to initialize the memory. - -To access the memory in hardware, ports can be obtained by calling the ``get_port`` method. A port always has an address signal ``a`` and a data read signal ``dat_r``. Other signals may be available depending on the port's configuration. - -Options to ``get_port`` are: - -* ``write_capable`` (default: ``False``): if the port can be used to write to the memory. This creates an additional ``we`` signal. -* ``async_read`` (default: ``False``): whether reads are asychronous (combinatorial) or synchronous (registered). -* ``has_re`` (default: ``False``): adds a read clock-enable signal ``re`` (ignored for asychronous ports). -* ``we_granularity`` (default: ``0``): if non-zero, writes of less than a memory word can occur. The width of the ``we`` signal is increased to act as a selection signal for the sub-words. -* ``mode`` (default: ``WRITE_FIRST``, ignored for aynchronous ports). It can be: - - * ``READ_FIRST``: during a write, the previous value is read. - * ``WRITE_FIRST``: the written value is returned. - * ``NO_CHANGE``: the data read signal keeps its previous value on a write. - -* ``clock_domain`` (default: ``"sys"``): the clock domain used for reading and writing from this port. - -Migen generates behavioural V*HDL code that should be compatible with all simulators and, if the number of ports is <= 2, most FPGA synthesizers. If a specific code is needed, the memory handler can be overriden using the appropriate parameter of the V*HDL conversion function. - -Inline synthesis directives -=========================== - -Inline synthesis directives (pseudo-comments such as ``// synthesis attribute keep of clock_signal_name is true``) are supported using the ``SynthesisDirective`` object. Its constructor takes as parameters a string containing the body of the directive, and optional keyword parameters that are used to replace signal names similarly to the Python string method ``format``. The above example could be represented as follows: :: - - SynthesisDirective("attribute keep of {clksig} is true", clksig=clock_domain.clk) - -Modules -******* - -Modules play the same role as Verilog modules and VHDL entities. Similarly, they are organized in a tree structure. A FHDL module is a Python object that derives from the ``Module`` class. This class defines special attributes to be used by derived classes to describe their logic. They are explained below. - -Combinatorial statements -======================== - -A combinatorial statement is a statement that is executed whenever one of its inputs changes. - -Combinatorial statements are added to a module by using the ``comb`` special attribute. Like most module special attributes, it must be accessed using the ``+=`` incrementation operator, and either a single statement, a tuple of statements or a list of statements can appear on the right hand side. - -For example, the module below implements a OR gate: :: - - class ORGate(Module): - def __init__(self): - self.a = Signal() - self.b = Signal() - self.x = Signal() - - ### - - self.comb += x.eq(a | b) - -To improve code readability, it is recommended to place the interface of the module at the beginning of the ``__init__`` function, and separate it from the implementation using three hash signs. - -Synchronous statements -====================== - -A synchronous statements is a statement that is executed at each edge of some clock signal. - -They are added to a module by using the ``sync`` special attribute, which has the same properties as the ``comb`` attribute. - -The ``sync`` special attribute also has sub-attributes that correspond to abstract clock domains. For example, to add a statement to the clock domain named ``foo``, one would write ``self.sync.foo += statement``. The default clock domain is ``sys`` and writing ``self.sync += statement`` is equivalent to writing ``self.sync.sys += statement``. - -Submodules and specials -======================= - -Submodules and specials can be added by using the ``submodules`` and ``specials`` attributes respectively. This can be done in two ways: - -#. anonymously, by using the ``+=`` operator on the special attribute directly, e.g. ``self.submodules += some_other_module``. Like with the ``comb`` and ``sync`` attributes, a single module/special or a tuple or list can be specified. -#. by naming the submodule/special using a subattribute of the ``submodules`` or ``specials`` attribute, e.g. ``self.submodules.foo = module_foo``. The submodule/special is then accessible as an attribute of the object, e.g. ``self.foo`` (and not ``self.submodules.foo``). Only one submodule/special can be added at a time using this form. - -Clock domains -============= - -Specifying the implementation of a clock domain is done using the ``ClockDomain`` object. It contains the name of the clock domain, a clock signal that can be driven like any other signal in the design (for example, using a PLL instance), and optionally a reset signal. Clock domains without a reset signal are reset using e.g. ``initial`` statements in Verilog, which in many FPGA families initalize the registers during configuration. - -The name can be omitted if it can be extracted from the variable name. When using this automatic naming feature, prefixes ``_``, ``cd_`` and ``_cd_`` are removed. - -Clock domains are then added to a module using the ``clock_domains`` special attribute, which behaves exactly like ``submodules`` and ``specials``. - -Summary of special attributes -============================= - -.. table:: - - +--------------------------------------------+--------------------------------------------------------------+ - | Syntax | Action | - +============================================+==============================================================+ - | self.comb += stmt | Add combinatorial statement to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.comb += stmtA, stmtB | Add combinatorial statements A and B to current module. | - | | | - | self.comb += [stmtA, stmtB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.sync += stmt | Add synchronous statement to current module, in default | - | | clock domain sys. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.sync.foo += stmt | Add synchronous statement to current module, in clock domain | - | | foo. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.sync.foo += stmtA, stmtB | Add synchronous statements A and B to current module, in | - | | clock domain foo. | - | self.sync.foo += [stmtA, stmtB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.submodules += mod | Add anonymous submodule to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.submodules += modA, modB | Add anonymous submodules A and B to current module. | - | | | - | self.submodules += [modA, modB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.submodules.bar = mod | Add submodule named bar to current module. The submodule can | - | | then be accessed using self.bar. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.specials += spe | Add anonymous special to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.specials += speA, speB | Add anonymous specials A and B to current module. | - | | | - | self.specials += [speA, speB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.specials.bar = spe | Add special named bar to current module. The special can | - | | then be accessed using self.bar. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.clock_domains += cd | Add clock domain to current module. | - +--------------------------------------------+--------------------------------------------------------------+ - | self.clock_domains += cdA, cdB | Add clock domains A and B to current module. | - | | | - | self.clock_domains += [cdA, cdB] | | - +--------------------------------------------+--------------------------------------------------------------+ - | self.clock_domains.pix = ClockDomain() | Create and add clock domain pix to current module. The clock | - | | domain name is pix in all cases. It can be accessed using | - | self.clock_domains._pix = ClockDomain() | self.pix, self._pix, self.cd_pix and self._cd_pix, | - | | respectively. | - | self.clock_domains.cd_pix = ClockDomain() | | - | | | - | self.clock_domains._cd_pix = ClockDomain() | | - +--------------------------------------------+--------------------------------------------------------------+ - -Clock domain management -======================= - -When a module has named submodules that define one or several clock domains with the same name, those clock domain names are prefixed with the name of each submodule plus an underscore. - -An example use case of this feature is a system with two independent video outputs. Each video output module is made of a clock generator module that defines a clock domain ``pix`` and drives the clock signal, plus a driver module that has synchronous statements and other elements in clock domain ``pix``. The designer of the video output module can simply use the clock domain name ``pix`` in that module. In the top-level system module, the video output submodules are named ``video0`` and ``video1``. Migen then automatically renames the ``pix`` clock domain of each module to ``video0_pix`` and ``video1_pix``. Note that happens only because the clock domain is defined (using ClockDomain objects), not simply referenced (using e.g. synchronous statements) in the video output modules. - -Clock domain name overlap is an error condition when any of the submodules that defines the clock domains is anonymous. - -Finalization mechanism -====================== - -Sometimes, it is desirable that some of a module logic be created only after the user has finished manipulating that module. For example, the FSM module supports that states be defined dynamically, and the width of the state signal can be known only after all states have been added. One solution is to declare the final number of states in the FSM constructor, but this is not user-friendly. A better solution is to automatically create the state signal just before the FSM module is converted to V*HDL. Migen supports this using the so-called finalization mechanism. - -Modules can overload a ``do_finalize`` method that can create logic and is called using the algorithm below: - -#. Finalization of the current module begins. -#. If the module has already been finalized (e.g. manually), the procedure stops here. -#. Submodules of the current module are recursively finalized. -#. ``do_finalize`` is called for the current module. -#. Any new submodules created by the current module's ``do_finalize`` are recursively finalized. - -Finalization is automatically invoked at V*HDL conversion and at simulation. It can be manually invoked for any module by calling its ``finalize`` method. - -The clock domain management mechanism explained above happens during finalization. - -Conversion for synthesis -************************ - -Any FHDL module can be converted into synthesizable Verilog HDL. This is accomplished by using the ``convert`` function in the ``verilog`` module. - -The ``migen.build`` component provides scripts to interface third-party FPGA tools (from Xilinx, Altera and Lattice) to Migen, and a database of boards for the easy deployment of designs. diff --git a/litex/gen/doc/index.rst b/litex/gen/doc/index.rst deleted file mode 100644 index 36f73aa3..00000000 --- a/litex/gen/doc/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -Migen manual -############ - -.. toctree:: - :maxdepth: 2 - - introduction - fhdl - simulation - synthesis - reference diff --git a/litex/gen/doc/introduction.rst b/litex/gen/doc/introduction.rst deleted file mode 100644 index bc24e336..00000000 --- a/litex/gen/doc/introduction.rst +++ /dev/null @@ -1,73 +0,0 @@ -Introduction -############ - -Migen is a Python-based tool that aims at automating further the VLSI design process. - -Migen makes it possible to apply modern software concepts such as object-oriented programming and metaprogramming to design hardware. This results in more elegant and easily maintained designs and reduces the incidence of human errors. - -.. _background: - -Background -********** - -Even though the Milkymist system-on-chip [mm]_ had many successes, it suffers from several limitations stemming from its implementation in manually written Verilog HDL: - -.. [mm] http://m-labs.hk - -#. The "event-driven" paradigm of today's dominant hardware descriptions languages (Verilog and VHDL, collectively referred to as "V*HDL" in the rest of this document) is often too general. Today's FPGA architectures are optimized for the implementation of fully synchronous circuits. This means that the bulk of the code for an efficient FPGA design falls into three categories: - - #. Combinatorial statements - #. Synchronous statements - #. Initialization of registers at reset - - V*HDL do not follow this organization. This means that a lot of repetitive manual coding is needed, which brings sources of human errors, petty issues, and confusion for beginners: - - #. wire vs. reg in Verilog - #. forgetting to initialize a register at reset - #. deciding whether a combinatorial statement must go into a process/always block or not - #. simulation mismatches with combinatorial processes/always blocks - #. and more... - - A little-known fact about FPGAs is that many of them have the ability to initialize their registers from the bitstream contents. This can be done in a portable and standard way using an "initial" block in Verilog, and by affecting a value at the signal declaration in VHDL. This renders an explicit reset signal unnecessary in practice in some cases, which opens the way for further design optimization. However, this form of initialization is entirely not synthesizable for ASIC targets, and it is not easy to switch between the two forms of reset using V*HDL. - -#. V*HDL support for composite types is very limited. Signals having a record type in VHDL are unidirectional, which makes them clumsy to use e.g. in bus interfaces. There is no record type support in Verilog, which means that a lot of copy-and-paste has to be done when forwarding grouped signals. - -#. V*HDL support for procedurally generated logic is extremely limited. The most advanced forms of procedural generation of synthesizable logic that V*HDL offers are CPP-style directives in Verilog, combinatorial functions, and ``generate`` statements. Nothing really fancy, and it shows. To give a few examples: - - #. Building highly flexible bus interconnect is not possible. Even arbitrating any given number of bus masters for commonplace protocols such as Wishbone is difficult with the tools that V*HDL puts at our disposal. - #. Building a memory infrastructure (including bus interconnect, bridges and caches) that can automatically adapt itself at compile-time to any word size of the SDRAM is clumsy and tedious. - #. Building register banks for control, status and interrupt management of cores can also largely benefit from automation. - #. Many hardware acceleration problems can fit into the dataflow programming model. Manual dataflow implementation in V*HDL has, again, a lot of redundancy and potential for human errors. See the Milkymist texture mapping unit [mthesis]_ [mxcell]_ for an example of this. The amount of detail to deal with manually also makes the design space exploration difficult, and therefore hinders the design of efficient architectures. - #. Pre-computation of values, such as filter coefficients for DSP or even simply trigonometric tables, must often be done using external tools whose results are copy-and-pasted (in the best case, automatically) into the V*HDL source. - -.. [mthesis] http://m-labs.hk/thesis/thesis.pdf -.. [mxcell] http://www.xilinx.com/publications/archives/xcell/Xcell77.pdf p30-35 - -Enter Migen, a Python toolbox for building complex digital hardware. We could have designed a brand new programming language, but that would have been reinventing the wheel instead of being able to benefit from Python's rich features and immense library. The price to pay is a slightly cluttered syntax at times when writing descriptions in FHDL, but we believe this is totally acceptable, particularly when compared to VHDL ;-) - -Migen is made up of several related components: - -#. the base language, FHDL -#. a library of small generic cores -#. a simulator -#. a build system - -Installing Migen -**************** - -Either run the ``setup.py`` installation script or simply set ``PYTHONPATH`` to the root of the source directory. - -If you wish to contribute patches, the suggest way to install is; - #. Clone from the git repository at http://github.com/m-labs/migen - #. Install using ``python3 ./setup.py develop --user`` - #. Edit the code in your git checkout. - -Alternative install methods -=========================== - - * Migen is available for the Anaconda Python distribution. The package can be found at at https://anaconda.org/m-labs/migen - * Migen can be referenced in a requirements.txt file (used for ``pip install -r requirements.txt``) via ``-e git+http://github.com/m-labs/migen.git#egg=migen``. See the pip documentation for more information. - -Feedback -******** -Feedback concerning Migen or this manual should be sent to the M-Labs developers' mailing list ``devel`` on lists.m-labs.hk. diff --git a/litex/gen/doc/migen_logo.png b/litex/gen/doc/migen_logo.png deleted file mode 100644 index 8c86fc04604c7c3113f61721b393a9a6d723701e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 74931 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 TgR8Hhl^4&OoGUy-xb;5(+tqtZ diff --git a/litex/gen/doc/migen_logo.svg b/litex/gen/doc/migen_logo.svg deleted file mode 100644 index fdb855ec..00000000 --- a/litex/gen/doc/migen_logo.svg +++ /dev/null @@ -1,224 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - image/svg+xml - - - - - - - - - - - - - - - migen - - - - diff --git a/litex/gen/doc/reference.rst b/litex/gen/doc/reference.rst deleted file mode 100644 index bec65ce8..00000000 --- a/litex/gen/doc/reference.rst +++ /dev/null @@ -1,37 +0,0 @@ -API reference -============= - -:mod:`fhdl.structure` module ----------------------------- - -.. automodule:: migen.fhdl.structure - :members: - :show-inheritance: - -:mod:`fhdl.bitcontainer` module -------------------------------- - -.. automodule:: migen.fhdl.bitcontainer - :members: - :show-inheritance: - -:mod:`genlib.fifo` module -------------------------- - -.. automodule:: migen.genlib.fifo - :members: - :show-inheritance: - -:mod:`genlib.coding` module ---------------------------- - -.. automodule:: migen.genlib.coding - :members: - :show-inheritance: - -:mod:`genlib.sort` module -------------------------- - -.. automodule:: migen.genlib.sort - :members: - :show-inheritance: diff --git a/litex/gen/doc/simulation.rst b/litex/gen/doc/simulation.rst deleted file mode 100644 index eff0ba5f..00000000 --- a/litex/gen/doc/simulation.rst +++ /dev/null @@ -1,6 +0,0 @@ -Simulating a Migen design -######################### - -Migen allows you to easily simulate your FHDL design and interface it with arbitrary Python code. The simulator is written in pure Python and interprets the FHDL structure directly without using an external Verilog simulator. - -[To be rewritten] diff --git a/litex/gen/doc/synthesis.rst b/litex/gen/doc/synthesis.rst deleted file mode 100644 index a5b99502..00000000 --- a/litex/gen/doc/synthesis.rst +++ /dev/null @@ -1,4 +0,0 @@ -Synthesizing a Migen design -########################### - -[To be written] diff --git a/litex/gen/examples/basic/arrays.py b/litex/gen/examples/basic/arrays.py deleted file mode 100644 index 0753107c..00000000 --- a/litex/gen/examples/basic/arrays.py +++ /dev/null @@ -1,28 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self): - dx = 2 - dy = 2 - - x = Signal(max=dx) - y = Signal(max=dy) - out = Signal() - - my_2d_array = Array(Array(Signal() for a in range(dx)) for b in range(dy)) - self.comb += out.eq(my_2d_array[x][y]) - - we = Signal() - inp = Signal() - self.sync += If(we, - my_2d_array[x][y].eq(inp) - ) - - ina = Array(Signal() for a in range(dx)) - outa = Array(Signal() for a in range(dy)) - self.specials += Instance("test", o_O=outa[y], i_I=ina[x]) - -if __name__ == "__main__": - print(verilog.convert(Example())) diff --git a/litex/gen/examples/basic/fsm.py b/litex/gen/examples/basic/fsm.py deleted file mode 100644 index ca235bfe..00000000 --- a/litex/gen/examples/basic/fsm.py +++ /dev/null @@ -1,31 +0,0 @@ -from migen import * -from migen.fhdl import verilog - -class Example(Module): - def __init__(self): - self.s = Signal() - self.counter = Signal(8) - x = Array(Signal(name="a") for i in range(7)) - - myfsm = FSM() - self.submodules += myfsm - - myfsm.act("FOO", - self.s.eq(1), - NextState("BAR") - ) - myfsm.act("BAR", - self.s.eq(0), - NextValue(self.counter, self.counter + 1), - NextValue(x[self.counter], 89), - NextState("FOO") - ) - - self.be = myfsm.before_entering("FOO") - self.ae = myfsm.after_entering("FOO") - self.bl = myfsm.before_leaving("FOO") - self.al = myfsm.after_leaving("FOO") - -if __name__ == "__main__": - example = Example() - print(verilog.convert(example, {example.s, example.counter, example.be, example.ae, example.bl, example.al})) diff --git a/litex/gen/examples/basic/graycounter.py b/litex/gen/examples/basic/graycounter.py deleted file mode 100644 index 28865a24..00000000 --- a/litex/gen/examples/basic/graycounter.py +++ /dev/null @@ -1,18 +0,0 @@ -from random import Random - -from migen import * -from migen.genlib.cdc import GrayCounter - - -def tb(dut): - prng = Random(7345) - for i in range(35): - print("{0:0{1}b} CE={2} bin={3}".format((yield dut.q), - len(dut.q), (yield dut.ce), (yield dut.q_binary))) - yield dut.ce.eq(prng.getrandbits(1)) - yield - - -if __name__ == "__main__": - dut = GrayCounter(3) - run_simulation(dut, tb(dut), vcd_name="graycounter.vcd") diff --git a/litex/gen/examples/basic/instance.py b/litex/gen/examples/basic/instance.py deleted file mode 100644 index fcabecc1..00000000 --- a/litex/gen/examples/basic/instance.py +++ /dev/null @@ -1,68 +0,0 @@ -import subprocess - -from migen import * -from migen.fhdl.verilog import convert - - -# Create a parent module with two instances of a child module. -# Bind input ports to first module and output ports to second, -# and create internal signals to connect the first module to the -# second. -class ParentModule(Module): - def __init__(self): - self.inputs = [Signal(x+1, name="input{}".format(x)) for x in range(4)] - self.trans = [Signal(x+1) for x in range(4)] - self.outputs = [Signal(x+1, name="output{}".format(x)) for x in range(4)] - self.io = set(self.inputs) | set(self.outputs) - i = Instance("ChildModule", - i_master_clk=ClockSignal(), - i_master_rst=ResetSignal(), - i_input0=self.inputs[0], - i_input1=self.inputs[1], - i_input2=self.inputs[2], - i_input3=self.inputs[3], - o_output0=self.trans[0], - o_output1=self.trans[1], - o_output2=self.trans[2], - o_output3=self.trans[3] - ) - j = Instance("ChildModule", - i_master_clk=ClockSignal(), - i_master_rst=ResetSignal(), - i_input0=self.trans[0], - i_input1=self.trans[1], - i_input2=self.trans[2], - i_input3=self.trans[3], - o_output0=self.outputs[0], - o_output1=self.outputs[1], - o_output2=self.outputs[2], - o_output3=self.outputs[3] - ) - self.specials += i, j - - -class ChildModule(Module): - def __init__(self): - self.inputs = [Signal(x+1, name_override="input{}".format(x)) for x in range(4)] - self.outputs = [Signal(x+1, name_override="output{}".format(x)) for x in range(4)] - self.io = set() - for x in range(4): - self.sync.master += self.outputs[x].eq(self.inputs[x]) - self.io = self.io.union(self.inputs) - self.io = self.io.union(self.outputs) - - -# Generate RTL for the parent module and the submodule, run through -# icarus for a syntax check -def test_instance_module(): - sub = ChildModule() - convert(sub, sub.io, name="ChildModule").write("ChildModule.v") - - im = ParentModule() - convert(im, im.io, name="ParentModule").write("ParentModule.v") - - subprocess.check_call(["iverilog", "-W", "all", - "ParentModule.v", "ChildModule.v"]) - -if __name__ == "__main__": - test_instance_module() diff --git a/litex/gen/examples/basic/local_cd.py b/litex/gen/examples/basic/local_cd.py deleted file mode 100644 index dc055060..00000000 --- a/litex/gen/examples/basic/local_cd.py +++ /dev/null @@ -1,19 +0,0 @@ -from migen import * -from migen.fhdl import verilog -from migen.genlib.divider import Divider - - -class CDM(Module): - def __init__(self): - self.submodules.divider = Divider(5) - self.clock_domains.cd_sys = ClockDomain(reset_less=True) - - -class MultiMod(Module): - def __init__(self): - self.submodules.foo = CDM() - self.submodules.bar = CDM() - -if __name__ == "__main__": - mm = MultiMod() - print(verilog.convert(mm, {mm.foo.cd_sys.clk, mm.bar.cd_sys.clk})) diff --git a/litex/gen/examples/basic/memory.py b/litex/gen/examples/basic/memory.py deleted file mode 100644 index 6b9c1f2c..00000000 --- a/litex/gen/examples/basic/memory.py +++ /dev/null @@ -1,17 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self): - self.specials.mem = Memory(32, 100, init=[5, 18, 32]) - p1 = self.mem.get_port(write_capable=True, we_granularity=8) - p2 = self.mem.get_port(has_re=True, clock_domain="rd") - self.specials += p1, p2 - self.ios = {p1.adr, p1.dat_r, p1.we, p1.dat_w, - p2.adr, p2.dat_r, p2.re} - - -if __name__ == "__main__": - example = Example() - print(verilog.convert(example, example.ios)) diff --git a/litex/gen/examples/basic/namer.py b/litex/gen/examples/basic/namer.py deleted file mode 100644 index 0c30c814..00000000 --- a/litex/gen/examples/basic/namer.py +++ /dev/null @@ -1,44 +0,0 @@ -from migen import * -from migen.fhdl import verilog - -from functools import reduce -from operator import or_ - - -def gen_list(n): - s = [Signal() for i in range(n)] - return s - - -def gen_2list(n): - s = [Signal(2) for i in range(n)] - return s - - -class Foo: - def __init__(self): - la = gen_list(3) - lb = gen_2list(2) - self.sigs = la + lb - - -class Bar: - def __init__(self): - self.sigs = gen_list(2) - - -class Example(Module): - def __init__(self): - a = [Bar() for x in range(3)] - b = [Foo() for x in range(3)] - c = b - b = [Bar() for x in range(2)] - - output = Signal() - allsigs = [] - for lst in [a, b, c]: - for obj in lst: - allsigs.extend(obj.sigs) - self.comb += output.eq(reduce(or_, allsigs)) - -print(verilog.convert(Example())) diff --git a/litex/gen/examples/basic/psync.py b/litex/gen/examples/basic/psync.py deleted file mode 100644 index 034ca69f..00000000 --- a/litex/gen/examples/basic/psync.py +++ /dev/null @@ -1,23 +0,0 @@ -from migen import * -from migen.fhdl.specials import SynthesisDirective -from migen.fhdl import verilog -from migen.genlib.cdc import * - - -class XilinxMultiRegImpl(MultiRegImpl): - def __init__(self, *args, **kwargs): - MultiRegImpl.__init__(self, *args, **kwargs) - self.specials += set(SynthesisDirective("attribute shreg_extract of {r} is no", r=r) - for r in self.regs) - - -class XilinxMultiReg: - @staticmethod - def lower(dr): - return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) - - -if __name__ == "__main__": - ps = PulseSynchronizer("from", "to") - v = verilog.convert(ps, {ps.i, ps.o}, special_overrides={MultiReg: XilinxMultiReg}) - print(v) diff --git a/litex/gen/examples/basic/record.py b/litex/gen/examples/basic/record.py deleted file mode 100644 index 59e72774..00000000 --- a/litex/gen/examples/basic/record.py +++ /dev/null @@ -1,26 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -L = [ - ("position", [ - ("x", 10, DIR_M_TO_S), - ("y", 10, DIR_M_TO_S), - ]), - ("color", 32, DIR_M_TO_S), - ("stb", 1, DIR_M_TO_S), - ("ack", 1, DIR_S_TO_M) -] - - -class Test(Module): - def __init__(self): - master = Record(L) - slave = Record(L) - self.comb += master.connect(slave) - - -if __name__ == "__main__": - print(verilog.convert(Test())) - print(layout_len(L)) - print(layout_partial(L, "position/x", "color")) diff --git a/litex/gen/examples/basic/reslice.py b/litex/gen/examples/basic/reslice.py deleted file mode 100644 index c5fb502a..00000000 --- a/litex/gen/examples/basic/reslice.py +++ /dev/null @@ -1,19 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self): - a = Signal(3) - b = Signal(4) - c = Signal(5) - d = Signal(7) - s1 = c[:3][:2] - s2 = Cat(a, b)[:6] - s3 = Cat(s1, s2)[-5:] - self.comb += s3.eq(0) - self.comb += d.eq(Cat(d[::-1], Cat(s1[:1], s3[-4:])[:3])) - - -if __name__ == "__main__": - print(verilog.convert(Example())) diff --git a/litex/gen/examples/basic/tristate.py b/litex/gen/examples/basic/tristate.py deleted file mode 100644 index 51afa033..00000000 --- a/litex/gen/examples/basic/tristate.py +++ /dev/null @@ -1,13 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class Example(Module): - def __init__(self, n=6): - self.pad = Signal(n) - self.t = TSTriple(n) - self.specials += self.t.get_tristate(self.pad) - -if __name__ == "__main__": - e = Example() - print(verilog.convert(e, ios={e.pad, e.t.o, e.t.oe, e.t.i})) diff --git a/litex/gen/examples/basic/two_dividers.py b/litex/gen/examples/basic/two_dividers.py deleted file mode 100644 index 6869d548..00000000 --- a/litex/gen/examples/basic/two_dividers.py +++ /dev/null @@ -1,19 +0,0 @@ -from migen import * -from migen.fhdl import verilog -from migen.genlib import divider - - -@ResetInserter() -@CEInserter() -class Example(Module): - def __init__(self, width): - d1 = divider.Divider(width) - d2 = divider.Divider(width) - self.submodules += d1, d2 - self.ios = { - d1.ready_o, d1.quotient_o, d1.remainder_o, d1.start_i, d1.dividend_i, d1.divisor_i, - d2.ready_o, d2.quotient_o, d2.remainder_o, d2.start_i, d2.dividend_i, d2.divisor_i} - -if __name__ == "__main__": - example = Example(16) - print(verilog.convert(example, example.ios | {example.ce, example.reset})) diff --git a/litex/gen/examples/sim/basic1.py b/litex/gen/examples/sim/basic1.py deleted file mode 100644 index 62afd21b..00000000 --- a/litex/gen/examples/sim/basic1.py +++ /dev/null @@ -1,29 +0,0 @@ -from migen import * - - -# Our simple counter, which increments at every cycle. -class Counter(Module): - def __init__(self): - self.count = Signal(4) - - # At each cycle, increase the value of the count signal. - # We do it with convertible/synthesizable FHDL code. - self.sync += self.count.eq(self.count + 1) - - -# Simply read the count signal and print it. -# The output is: -# Count: 0 -# Count: 1 -# Count: 2 -# ... -def counter_test(dut): - for i in range(20): - print((yield dut.count)) # read and print - yield # next clock cycle - # simulation ends with this generator - - -if __name__ == "__main__": - dut = Counter() - run_simulation(dut, counter_test(dut), vcd_name="basic1.vcd") diff --git a/litex/gen/examples/sim/basic2.py b/litex/gen/examples/sim/basic2.py deleted file mode 100644 index 45bc676f..00000000 --- a/litex/gen/examples/sim/basic2.py +++ /dev/null @@ -1,37 +0,0 @@ -from migen import * - - -# A slightly more elaborate counter. -# Has a clock enable (CE) signal, counts on more bits -# and resets with a negative number. -class Counter(Module): - def __init__(self): - self.ce = Signal() - # Demonstrate negative numbers and signals larger than 32 bits. - self.count = Signal((37, True), reset=-5) - - self.sync += If(self.ce, self.count.eq(self.count + 1)) - - -def counter_test(dut): - for cycle in range(20): - # Only assert CE every second cycle. - # => each counter value is held for two cycles. - if cycle % 2: - yield dut.ce.eq(0) # This is how you write to a signal. - else: - yield dut.ce.eq(1) - print("Cycle: {} Count: {}".format(cycle, (yield dut.count))) - yield - -# Output is: -# Cycle: 0 Count: -5 -# Cycle: 1 Count: -5 -# Cycle: 2 Count: -4 -# Cycle: 3 Count: -4 -# Cycle: 4 Count: -3 -# ... - -if __name__ == "__main__": - dut = Counter() - run_simulation(dut, counter_test(dut), vcd_name="basic2.vcd") diff --git a/litex/gen/examples/sim/fir.py b/litex/gen/examples/sim/fir.py deleted file mode 100644 index 67a78bc7..00000000 --- a/litex/gen/examples/sim/fir.py +++ /dev/null @@ -1,67 +0,0 @@ -from functools import reduce -from operator import add - -from math import cos, pi -from scipy import signal -import matplotlib.pyplot as plt - -from migen import * -from migen.fhdl import verilog - - -# A synthesizable FIR filter. -class FIR(Module): - def __init__(self, coef, wsize=16): - self.coef = coef - self.wsize = wsize - self.i = Signal((self.wsize, True)) - self.o = Signal((self.wsize, True)) - - ### - - muls = [] - src = self.i - for c in self.coef: - sreg = Signal((self.wsize, True)) - self.sync += sreg.eq(src) - src = sreg - c_fp = int(c*2**(self.wsize - 1)) - muls.append(c_fp*sreg) - sum_full = Signal((2*self.wsize-1, True)) - self.sync += sum_full.eq(reduce(add, muls)) - self.comb += self.o.eq(sum_full >> self.wsize-1) - - -# A test bench for our FIR filter. -# Generates a sine wave at the input and records the output. -def fir_tb(dut, frequency, inputs, outputs): - f = 2**(dut.wsize - 1) - for cycle in range(200): - v = 0.1*cos(2*pi*frequency*cycle) - yield dut.i.eq(int(f*v)) - inputs.append(v) - outputs.append((yield dut.o)/f) - yield - - -if __name__ == "__main__": - # Compute filter coefficients with SciPy. - coef = signal.remez(30, [0, 0.1, 0.2, 0.4, 0.45, 0.5], [0, 1, 0]) - - # Simulate for different frequencies and concatenate - # the results. - in_signals = [] - out_signals = [] - for frequency in [0.05, 0.1, 0.25]: - dut = FIR(coef) - tb = fir_tb(dut, frequency, in_signals, out_signals) - run_simulation(dut, tb) - - # Plot data from the input and output waveforms. - plt.plot(in_signals) - plt.plot(out_signals) - plt.show() - - # Print the Verilog source for the filter. - fir = FIR(coef) - print(verilog.convert(fir, ios={fir.i, fir.o})) diff --git a/litex/gen/examples/sim/memory.py b/litex/gen/examples/sim/memory.py deleted file mode 100644 index 51a0c329..00000000 --- a/litex/gen/examples/sim/memory.py +++ /dev/null @@ -1,26 +0,0 @@ -from migen import * - - -class Mem(Module): - def __init__(self): - # Initialize the beginning of the memory with integers - # from 0 to 19. - self.specials.mem = Memory(16, 2**12, init=list(range(20))) - - -def memory_test(dut): - # write (only first 5 values) - for i in range(5): - yield dut.mem[i].eq(42 + i) - # remember: values are written after the tick, and read before the tick. - # wait one tick for the memory to update. - yield - # read what we have written, plus some initialization data - for i in range(10): - value = yield dut.mem[i] - print(value) - - -if __name__ == "__main__": - dut = Mem() - run_simulation(dut, memory_test(dut)) diff --git a/litex/gen/migen/util/__init__.py b/litex/gen/fhdl/__init__.py similarity index 100% rename from litex/gen/migen/util/__init__.py rename to litex/gen/fhdl/__init__.py diff --git a/migen/fhdl/bitcontainer.py b/litex/gen/fhdl/bitcontainer.py similarity index 98% rename from migen/fhdl/bitcontainer.py rename to litex/gen/fhdl/bitcontainer.py index 15a68d0b..11a3ede7 100644 --- a/migen/fhdl/bitcontainer.py +++ b/litex/gen/fhdl/bitcontainer.py @@ -1,4 +1,4 @@ -from migen.fhdl import structure as f +from litex.gen.fhdl import structure as f __all__ = ["log2_int", "bits_for", "value_bits_sign"] diff --git a/litex/gen/migen/fhdl/conv_output.py b/litex/gen/fhdl/conv_output.py similarity index 100% rename from litex/gen/migen/fhdl/conv_output.py rename to litex/gen/fhdl/conv_output.py diff --git a/litex/gen/migen/fhdl/decorators.py b/litex/gen/fhdl/decorators.py similarity index 95% rename from litex/gen/migen/fhdl/decorators.py rename to litex/gen/fhdl/decorators.py index 694479c5..59444eaf 100644 --- a/litex/gen/migen/fhdl/decorators.py +++ b/litex/gen/fhdl/decorators.py @@ -1,6 +1,6 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.tools import insert_reset, rename_clock_domain +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.tools import insert_reset, rename_clock_domain __all__ = ["CEInserter", "ResetInserter", "ClockDomainsRenamer", diff --git a/migen/fhdl/edif.py b/litex/gen/fhdl/edif.py similarity index 96% rename from migen/fhdl/edif.py rename to litex/gen/fhdl/edif.py index f6d7deb0..f68c99bd 100644 --- a/migen/fhdl/edif.py +++ b/litex/gen/fhdl/edif.py @@ -1,10 +1,10 @@ from collections import OrderedDict, namedtuple -from migen.fhdl.structure import * -from migen.fhdl.namer import build_namespace -from migen.fhdl.tools import list_special_ios -from migen.fhdl.structure import _Fragment -from migen.fhdl.conv_output import ConvOutput +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.namer import build_namespace +from litex.gen.fhdl.tools import list_special_ios +from litex.gen.fhdl.structure import _Fragment +from litex.gen.fhdl.conv_output import ConvOutput _Port = namedtuple("_Port", "name direction") diff --git a/migen/fhdl/module.py b/litex/gen/fhdl/module.py similarity index 96% rename from migen/fhdl/module.py rename to litex/gen/fhdl/module.py index 7a209933..a8607514 100644 --- a/migen/fhdl/module.py +++ b/litex/gen/fhdl/module.py @@ -1,10 +1,10 @@ import collections from itertools import combinations -from migen.util.misc import flat_iteration -from migen.fhdl.structure import * -from migen.fhdl.structure import _Fragment -from migen.fhdl.tools import rename_clock_domain +from litex.gen.util.misc import flat_iteration +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.structure import _Fragment +from litex.gen.fhdl.tools import rename_clock_domain __all__ = ["Module", "FinalizeError"] diff --git a/litex/gen/migen/fhdl/namer.py b/litex/gen/fhdl/namer.py similarity index 98% rename from litex/gen/migen/fhdl/namer.py rename to litex/gen/fhdl/namer.py index 8e0f450d..5e8ecdd3 100644 --- a/litex/gen/migen/fhdl/namer.py +++ b/litex/gen/fhdl/namer.py @@ -1,7 +1,7 @@ from collections import OrderedDict from itertools import combinations -from migen.fhdl.structure import * +from litex.gen.fhdl.structure import * class _Node: @@ -14,7 +14,7 @@ class _Node: def _display_tree(filename, tree): - from migen.util.treeviz import RenderNode + from litex.gen.util.treeviz import RenderNode def _to_render_node(name, node): children = [_to_render_node(k, v) for k, v in node.children.items()] diff --git a/migen/fhdl/simplify.py b/litex/gen/fhdl/simplify.py similarity index 95% rename from migen/fhdl/simplify.py rename to litex/gen/fhdl/simplify.py index dba41beb..747f5628 100644 --- a/migen/fhdl/simplify.py +++ b/litex/gen/fhdl/simplify.py @@ -1,7 +1,7 @@ -from migen.fhdl.structure import * -from migen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE -from migen.fhdl.decorators import ModuleTransformer -from migen.util.misc import gcd_multiple +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE +from litex.gen.fhdl.decorators import ModuleTransformer +from litex.gen.util.misc import gcd_multiple class FullMemoryWE(ModuleTransformer): diff --git a/migen/fhdl/specials.py b/litex/gen/fhdl/specials.py similarity index 97% rename from migen/fhdl/specials.py rename to litex/gen/fhdl/specials.py index bd3e1bf5..d4fc2bf1 100644 --- a/migen/fhdl/specials.py +++ b/litex/gen/fhdl/specials.py @@ -1,11 +1,11 @@ from operator import itemgetter -from migen.fhdl.structure import * -from migen.fhdl.structure import _Value -from migen.fhdl.bitcontainer import bits_for, value_bits_sign -from migen.fhdl.tools import * -from migen.fhdl.tracer import get_obj_var_name -from migen.fhdl.verilog import _printexpr as verilog_printexpr +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.structure import _Value +from litex.gen.fhdl.bitcontainer import bits_for, value_bits_sign +from litex.gen.fhdl.tools import * +from litex.gen.fhdl.tracer import get_obj_var_name +from litex.gen.fhdl.verilog import _printexpr as verilog_printexpr __all__ = ["TSTriple", "Instance", "Memory", diff --git a/migen/fhdl/structure.py b/litex/gen/fhdl/structure.py similarity index 98% rename from migen/fhdl/structure.py rename to litex/gen/fhdl/structure.py index f4250266..7e6d2ca5 100644 --- a/migen/fhdl/structure.py +++ b/litex/gen/fhdl/structure.py @@ -1,8 +1,8 @@ import builtins as _builtins import collections as _collections -from migen.fhdl import tracer as _tracer -from migen.util.misc import flat_iteration as _flat_iteration +from litex.gen.fhdl import tracer as _tracer +from litex.gen.util.misc import flat_iteration as _flat_iteration class DUID: @@ -90,7 +90,7 @@ class _Value(DUID): return _Operator(">=", [self, other]) def __len__(self): - from migen.fhdl.bitcontainer import value_bits_sign + from litex.gen.fhdl.bitcontainer import value_bits_sign return value_bits_sign(self)[0] def __getitem__(self, key): @@ -246,7 +246,7 @@ class Constant(_Value): to the minimum width and signedness of `value`. """ def __init__(self, value, bits_sign=None): - from migen.fhdl.bitcontainer import bits_for + from litex.gen.fhdl.bitcontainer import bits_for _Value.__init__(self) @@ -311,7 +311,7 @@ class Signal(_Value): related : Signal or None """ def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None): - from migen.fhdl.bitcontainer import bits_for + from litex.gen.fhdl.bitcontainer import bits_for _Value.__init__(self) @@ -359,7 +359,7 @@ class Signal(_Value): See `migen.fhdl.bitcontainer.value_bits_sign` for details. """ - from migen.fhdl.bitcontainer import value_bits_sign + from litex.gen.fhdl.bitcontainer import value_bits_sign return cls(bits_sign=value_bits_sign(other), **kwargs) def __hash__(self): diff --git a/litex/gen/migen/fhdl/tools.py b/litex/gen/fhdl/tools.py similarity index 96% rename from litex/gen/migen/fhdl/tools.py rename to litex/gen/fhdl/tools.py index ddc135c2..3db91831 100644 --- a/litex/gen/migen/fhdl/tools.py +++ b/litex/gen/fhdl/tools.py @@ -1,8 +1,8 @@ -from migen.fhdl.structure import * -from migen.fhdl.structure import _Slice, _Assign -from migen.fhdl.visit import NodeVisitor, NodeTransformer -from migen.fhdl.bitcontainer import value_bits_sign -from migen.util.misc import flat_iteration +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.structure import _Slice, _Assign +from litex.gen.fhdl.visit import NodeVisitor, NodeTransformer +from litex.gen.fhdl.bitcontainer import value_bits_sign +from litex.gen.util.misc import flat_iteration class _SignalLister(NodeVisitor): diff --git a/litex/gen/migen/fhdl/tracer.py b/litex/gen/fhdl/tracer.py similarity index 100% rename from litex/gen/migen/fhdl/tracer.py rename to litex/gen/fhdl/tracer.py diff --git a/litex/gen/migen/fhdl/verilog.py b/litex/gen/fhdl/verilog.py similarity index 97% rename from litex/gen/migen/fhdl/verilog.py rename to litex/gen/fhdl/verilog.py index 19bba1fa..acca5f52 100644 --- a/litex/gen/migen/fhdl/verilog.py +++ b/litex/gen/fhdl/verilog.py @@ -2,12 +2,12 @@ from functools import partial from operator import itemgetter import collections -from migen.fhdl.structure import * -from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment -from migen.fhdl.tools import * -from migen.fhdl.bitcontainer import bits_for -from migen.fhdl.namer import build_namespace -from migen.fhdl.conv_output import ConvOutput +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment +from litex.gen.fhdl.tools import * +from litex.gen.fhdl.bitcontainer import bits_for +from litex.gen.fhdl.namer import build_namespace +from litex.gen.fhdl.conv_output import ConvOutput _reserved_keywords = { @@ -346,7 +346,7 @@ def convert(f, ios=None, name="top", ns.clock_domains = f.clock_domains r.ns = ns - src = "/* Machine-generated using Migen */\n" + src = "/* Machine-generated using LiteX */\n" src += _printheader(f, ios, name, ns, reg_initialization=not asic_syntax) src += _printcomb(f, ns, diff --git a/litex/gen/migen/fhdl/visit.py b/litex/gen/fhdl/visit.py similarity index 98% rename from litex/gen/migen/fhdl/visit.py rename to litex/gen/fhdl/visit.py index dd3ebbd7..0ccd5095 100644 --- a/litex/gen/migen/fhdl/visit.py +++ b/litex/gen/fhdl/visit.py @@ -1,7 +1,7 @@ from copy import copy -from migen.fhdl.structure import * -from migen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy, +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy, _Fragment) diff --git a/litex/soc/misoc/__init__.py b/litex/gen/genlib/__init__.py similarity index 100% rename from litex/soc/misoc/__init__.py rename to litex/gen/genlib/__init__.py diff --git a/migen/genlib/cdc.py b/litex/gen/genlib/cdc.py similarity index 94% rename from migen/genlib/cdc.py rename to litex/gen/genlib/cdc.py index c5342b7b..90b5f907 100644 --- a/migen/genlib/cdc.py +++ b/litex/gen/genlib/cdc.py @@ -1,8 +1,8 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.specials import Special -from migen.fhdl.bitcontainer import value_bits_sign -from migen.genlib.misc import WaitTimer +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.specials import Special +from litex.gen.fhdl.bitcontainer import value_bits_sign +from litex.gen.genlib.misc import WaitTimer class NoRetiming(Special): diff --git a/litex/gen/migen/genlib/coding.py b/litex/gen/genlib/coding.py similarity index 96% rename from litex/gen/migen/genlib/coding.py rename to litex/gen/genlib/coding.py index 6327b388..80d62d6d 100644 --- a/litex/gen/migen/genlib/coding.py +++ b/litex/gen/genlib/coding.py @@ -2,8 +2,8 @@ Encoders and decoders between binary and one-hot representation """ -from migen.fhdl.structure import * -from migen.fhdl.module import Module +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module class Encoder(Module): diff --git a/migen/genlib/divider.py b/litex/gen/genlib/divider.py similarity index 92% rename from migen/genlib/divider.py rename to litex/gen/genlib/divider.py index f31c7407..841e7ad0 100644 --- a/migen/genlib/divider.py +++ b/litex/gen/genlib/divider.py @@ -1,5 +1,5 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module class Divider(Module): diff --git a/migen/genlib/fifo.py b/litex/gen/genlib/fifo.py similarity index 95% rename from migen/genlib/fifo.py rename to litex/gen/genlib/fifo.py index 8f4e1423..167f9643 100644 --- a/migen/genlib/fifo.py +++ b/litex/gen/genlib/fifo.py @@ -1,9 +1,9 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.specials import Memory -from migen.fhdl.bitcontainer import log2_int -from migen.fhdl.decorators import ClockDomainsRenamer -from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.specials import Memory +from litex.gen.fhdl.bitcontainer import log2_int +from litex.gen.fhdl.decorators import ClockDomainsRenamer +from litex.gen.genlib.cdc import NoRetiming, MultiReg, GrayCounter def _inc(signal, modulo): diff --git a/litex/gen/migen/genlib/fsm.py b/litex/gen/genlib/fsm.py similarity index 95% rename from litex/gen/migen/genlib/fsm.py rename to litex/gen/genlib/fsm.py index e80eca10..de20e745 100644 --- a/litex/gen/migen/genlib/fsm.py +++ b/litex/gen/genlib/fsm.py @@ -1,10 +1,10 @@ from collections import OrderedDict -from migen.fhdl.structure import * -from migen.fhdl.structure import _Statement, _Slice, _ArrayProxy -from migen.fhdl.module import Module, FinalizeError -from migen.fhdl.visit import NodeTransformer -from migen.fhdl.bitcontainer import value_bits_sign +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.structure import _Statement, _Slice, _ArrayProxy +from litex.gen.fhdl.module import Module, FinalizeError +from litex.gen.fhdl.visit import NodeTransformer +from litex.gen.fhdl.bitcontainer import value_bits_sign __all__ = ["AnonymousState", "NextState", "NextValue", "FSM"] diff --git a/litex/gen/migen/genlib/io.py b/litex/gen/genlib/io.py similarity index 95% rename from litex/gen/migen/genlib/io.py rename to litex/gen/genlib/io.py index fc930125..5c441e66 100644 --- a/litex/gen/migen/genlib/io.py +++ b/litex/gen/genlib/io.py @@ -1,6 +1,6 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.specials import Special +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.specials import Special class DifferentialInput(Special): diff --git a/migen/genlib/misc.py b/litex/gen/genlib/misc.py similarity index 94% rename from migen/genlib/misc.py rename to litex/gen/genlib/misc.py index f8f4a7c4..42ad878c 100644 --- a/migen/genlib/misc.py +++ b/litex/gen/genlib/misc.py @@ -1,6 +1,6 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.bitcontainer import bits_for +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module +from litex.gen.fhdl.bitcontainer import bits_for def split(v, *counts): diff --git a/litex/gen/migen/genlib/record.py b/litex/gen/genlib/record.py similarity index 98% rename from litex/gen/migen/genlib/record.py rename to litex/gen/genlib/record.py index bf6aa619..0038b069 100644 --- a/litex/gen/migen/genlib/record.py +++ b/litex/gen/genlib/record.py @@ -1,5 +1,5 @@ -from migen.fhdl.structure import * -from migen.fhdl.tracer import get_obj_var_name +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.tracer import get_obj_var_name from functools import reduce from operator import or_ diff --git a/litex/gen/migen/genlib/resetsync.py b/litex/gen/genlib/resetsync.py similarity index 85% rename from litex/gen/migen/genlib/resetsync.py rename to litex/gen/genlib/resetsync.py index db936900..061f65bc 100644 --- a/litex/gen/migen/genlib/resetsync.py +++ b/litex/gen/genlib/resetsync.py @@ -1,5 +1,5 @@ -from migen.fhdl.structure import * -from migen.fhdl.specials import Special +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.specials import Special class AsyncResetSynchronizer(Special): diff --git a/litex/gen/migen/genlib/roundrobin.py b/litex/gen/genlib/roundrobin.py similarity index 93% rename from litex/gen/migen/genlib/roundrobin.py rename to litex/gen/genlib/roundrobin.py index 87ac5bb6..b9903dbb 100644 --- a/litex/gen/migen/genlib/roundrobin.py +++ b/litex/gen/genlib/roundrobin.py @@ -1,5 +1,5 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module (SP_WITHDRAW, SP_CE) = range(2) diff --git a/migen/genlib/sort.py b/litex/gen/genlib/sort.py similarity index 96% rename from migen/genlib/sort.py rename to litex/gen/genlib/sort.py index 8f38e629..ff5b6175 100644 --- a/migen/genlib/sort.py +++ b/litex/gen/genlib/sort.py @@ -1,5 +1,5 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module +from litex.gen.fhdl.structure import * +from litex.gen.fhdl.module import Module class BitonicSort(Module): diff --git a/litex/gen/migen/__init__.py b/litex/gen/migen/__init__.py deleted file mode 100644 index 492117f2..00000000 --- a/litex/gen/migen/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import * -from migen.fhdl.specials import * -from migen.fhdl.bitcontainer import * -from migen.fhdl.decorators import * - -from migen.sim import * - -from migen.genlib.record import * -from migen.genlib.fsm import * diff --git a/litex/gen/migen/build/altera/__init__.py b/litex/gen/migen/build/altera/__init__.py deleted file mode 100644 index 9fc45d4a..00000000 --- a/litex/gen/migen/build/altera/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from migen.build.altera.platform import AlteraPlatform -from migen.build.altera.programmer import USBBlaster diff --git a/litex/gen/migen/build/altera/platform.py b/litex/gen/migen/build/altera/platform.py deleted file mode 100644 index 43841fa7..00000000 --- a/litex/gen/migen/build/altera/platform.py +++ /dev/null @@ -1,27 +0,0 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.altera import common, quartus - - -class AlteraPlatform(GenericPlatform): - bitstream_ext = ".sof" - - def __init__(self, *args, toolchain="quartus", **kwargs): - GenericPlatform.__init__(self, *args, **kwargs) - if toolchain == "quartus": - self.toolchain = quartus.AlteraQuartusToolchain() - else: - raise ValueError("Unknown toolchain") - - def get_verilog(self, *args, special_overrides=dict(), **kwargs): - so = dict(common.altera_special_overrides) - so.update(special_overrides) - return GenericPlatform.get_verilog(self, *args, special_overrides=so, - **kwargs) - - def build(self, *args, **kwargs): - return self.toolchain.build(self, *args, **kwargs) - - def add_period_constraint(self, clk, period): - if hasattr(clk, "p"): - clk = clk.p - self.toolchain.add_period_constraint(self, clk, period) diff --git a/litex/gen/migen/build/altera/programmer.py b/litex/gen/migen/build/altera/programmer.py deleted file mode 100644 index 369f7db1..00000000 --- a/litex/gen/migen/build/altera/programmer.py +++ /dev/null @@ -1,13 +0,0 @@ -import subprocess - -from migen.build.generic_programmer import GenericProgrammer - - -class USBBlaster(GenericProgrammer): - needs_bitreverse = False - - def load_bitstream(self, bitstream_file, port=0): - usb_port = "[USB-{}]".format(port) - subprocess.call(["quartus_pgm", "-m", "jtag", "-c", - "USB-Blaster{}".format(usb_port), "-o", - "p;{}".format(bitstream_file)]) diff --git a/litex/gen/migen/build/fpgalink_programmer.py b/litex/gen/migen/build/fpgalink_programmer.py deleted file mode 100644 index fc7586dc..00000000 --- a/litex/gen/migen/build/fpgalink_programmer.py +++ /dev/null @@ -1,102 +0,0 @@ -import os - -from migen.build.generic_programmer import GenericProgrammer -from migen.build.xilinx.programmer import _create_xsvf - -try: - import fl -except ImportError: - import fpgalink3 as fl - -fl.flInitialise(0) - - -class FPGALink(GenericProgrammer): - """Using the fpgalink library from makestuff - - You will need fpgalink library installed from - https://github.com/makestuff/libfpgalink - """ - - needs_bitreverse = False - - def __init__(self, initial_vidpid=None, pin_cfg="D0D2D3D4", - fpgalink_vidpid="1D50:602B:0002", flash_proxy_basename=None): - """ - Parameters - ---------- - initial_vidpid : string - The USB vendor and product id of the device before fpgalink - firmware is loaded onto the device. - - Format is vid:pid as 4 digit hex numbers. - - pin_cfg : string - FPGALink pin configuration string describing how the JTAG interface - is hooked up to the programmer. - - fpgalink_vidpid : string - The USB vendor, product and device id of the device after the - fpgalink firmware is loaded onto the device. - - Format is vid:pid:did as 4 digit hex numbers. - Defaults to 1D50:602B:0002 which is the makestuff FPGALink device. - """ - GenericProgrammer.__init__(self, flash_proxy_basename) - self.initial_vidpid = initial_vidpid - self.fpgalink_vidpid = fpgalink_vidpid - self.pin_cfg = pin_cfg - - def open_device(self): - ivp = self.initial_vidpid - vp = self.fpgalink_vidpid - - print("Attempting to open connection to FPGALink device", vp, "...") - try: - handle = fl.flOpen(self.fpgalink_vidpid) - except fl.FLException as ex: - if not ivp: - raise FLException( - "Could not open FPGALink device at {0} and" - " no initial VID:PID was supplied".format(vp)) - - print("Loading firmware into %s..." % ivp) - fl.flLoadStandardFirmware(ivp, vp) - - print("Awaiting renumeration...") - if not fl.flAwaitDevice(vp, 600): - raise fl.FLException( - "FPGALink device did not renumerate properly" - " as {0}".format(vp)) - - print("Attempting to open connection to FPGALink device", vp, - "again...") - handle = fl.flOpen(vp) - - # Only Nero capable hardware support doing programming. - assert fl.flIsNeroCapable(handle) - print("Cable connection opened.") - return handle - - def load_bitstream(self, bitstream_file): - n = 27 - - xsvf_file = os.path.splitext(bitstream_file)[0]+'.xsvf' - print("\nGenerating xsvf formatted bitstream") - print("="*n) - if os.path.exists(xsvf_file): - os.unlink(xsvf_file) - _create_xsvf(bitstream_file, xsvf_file) - print("\n"+"="*n+"\n") - - print("Programming %s to device." % xsvf_file) - print("="*n) - handle = self.open_device() - print("Programming device...") - fl.flProgram(handle, "J:"+self.pin_cfg, progFile=xsvf_file) - print("Programming successful!") - print("="*n+"\n") - fl.flClose(handle) - - def flash(self, address, data_file): - raise NotImplementedError("Not supported yet.") diff --git a/litex/gen/migen/build/generic_platform.py b/litex/gen/migen/build/generic_platform.py deleted file mode 100644 index 5163d922..00000000 --- a/litex/gen/migen/build/generic_platform.py +++ /dev/null @@ -1,343 +0,0 @@ -import os - -from migen.fhdl.structure import Signal -from migen.genlib.record import Record -from migen.genlib.io import CRG -from migen.fhdl import verilog, edif -from migen.build import tools - - -class ConstraintError(Exception): - pass - - -class Pins: - def __init__(self, *identifiers): - self.identifiers = [] - for i in identifiers: - self.identifiers += i.split() - - def __repr__(self): - return "{}('{}')".format(self.__class__.__name__, - " ".join(self.identifiers)) - - -class IOStandard: - def __init__(self, name): - self.name = name - - def __repr__(self): - return "{}('{}')".format(self.__class__.__name__, self.name) - - -class Drive: - def __init__(self, strength): - self.strength = strength - - def __repr__(self): - return "{}('{}')".format(self.__class__.__name__, self.strength) - - -class Misc: - def __init__(self, misc): - self.misc = misc - - def __repr__(self): - return "{}({})".format(self.__class__.__name__, repr(self.misc)) - - -class Subsignal: - def __init__(self, name, *constraints): - self.name = name - self.constraints = list(constraints) - - def __repr__(self): - return "{}('{}', {})".format( - self.__class__.__name__, - self.name, - ", ".join([repr(constr) for constr in self.constraints])) - - -class PlatformInfo: - def __init__(self, info): - self.info = info - - def __repr__(self): - return "{}({})".format(self.__class__.__name__, repr(self.info)) - - -def _lookup(description, name, number): - for resource in description: - if resource[0] == name and (number is None or resource[1] == number): - return resource - raise ConstraintError("Resource not found: {}:{}".format(name, number)) - - -def _resource_type(resource): - t = None - for element in resource[2:]: - if isinstance(element, Pins): - assert(t is None) - t = len(element.identifiers) - elif isinstance(element, Subsignal): - if t is None: - t = [] - - assert(isinstance(t, list)) - n_bits = None - for c in element.constraints: - if isinstance(c, Pins): - assert(n_bits is None) - n_bits = len(c.identifiers) - - t.append((element.name, n_bits)) - - return t - - -class ConnectorManager: - def __init__(self, connectors): - self.connector_table = dict() - for connector in connectors: - cit = iter(connector) - conn_name = next(cit) - if isinstance(connector[1], str): - pin_list = [] - for pins in cit: - pin_list += pins.split() - pin_list = [None if pin == "None" else pin for pin in pin_list] - elif isinstance(connector[1], dict): - pin_list = connector[1] - else: - raise ValueError("Unsupported pin list type {} for connector" - " {}".format(type(connector[1]), conn_name)) - if conn_name in self.connector_table: - raise ValueError( - "Connector specified more than once: {}".format(conn_name)) - - self.connector_table[conn_name] = pin_list - - def resolve_identifiers(self, identifiers): - r = [] - for identifier in identifiers: - if ":" in identifier: - conn, pn = identifier.split(":") - if pn.isdigit(): - pn = int(pn) - - r.append(self.connector_table[conn][pn]) - else: - r.append(identifier) - - return r - - -def _separate_pins(constraints): - pins = None - others = [] - for c in constraints: - if isinstance(c, Pins): - assert(pins is None) - pins = c.identifiers - else: - others.append(c) - - return pins, others - - -class ConstraintManager: - def __init__(self, io, connectors): - self.available = list(io) - self.matched = [] - self.platform_commands = [] - self.connector_manager = ConnectorManager(connectors) - - def add_extension(self, io): - self.available.extend(io) - - def request(self, name, number=None): - resource = _lookup(self.available, name, number) - rt = _resource_type(resource) - if isinstance(rt, int): - obj = Signal(rt, name_override=resource[0]) - else: - obj = Record(rt, name=resource[0]) - - for element in resource[2:]: - if isinstance(element, PlatformInfo): - obj.platform_info = element.info - break - - self.available.remove(resource) - self.matched.append((resource, obj)) - return obj - - def lookup_request(self, name, number=None): - for resource, obj in self.matched: - if resource[0] == name and (number is None or - resource[1] == number): - return obj - - raise ConstraintError("Resource not found: {}:{}".format(name, number)) - - def add_platform_command(self, command, **signals): - self.platform_commands.append((command, signals)) - - def get_io_signals(self): - r = set() - for resource, obj in self.matched: - if isinstance(obj, Signal): - r.add(obj) - else: - r.update(obj.flatten()) - - return r - - def get_sig_constraints(self): - r = [] - for resource, obj in self.matched: - name = resource[0] - number = resource[1] - has_subsignals = False - top_constraints = [] - for element in resource[2:]: - if isinstance(element, Subsignal): - has_subsignals = True - else: - top_constraints.append(element) - - if has_subsignals: - for element in resource[2:]: - if isinstance(element, Subsignal): - sig = getattr(obj, element.name) - pins, others = _separate_pins(top_constraints + - element.constraints) - pins = self.connector_manager.resolve_identifiers(pins) - r.append((sig, pins, others, - (name, number, element.name))) - else: - pins, others = _separate_pins(top_constraints) - pins = self.connector_manager.resolve_identifiers(pins) - r.append((obj, pins, others, (name, number, None))) - - return r - - def get_platform_commands(self): - return self.platform_commands - - -class GenericPlatform: - def __init__(self, device, io, connectors=[], name=None): - self.device = device - self.constraint_manager = ConstraintManager(io, connectors) - if name is None: - name = self.__module__.split(".")[-1] - self.name = name - self.sources = set() - self.verilog_include_paths = set() - self.finalized = False - - def request(self, *args, **kwargs): - return self.constraint_manager.request(*args, **kwargs) - - def lookup_request(self, *args, **kwargs): - return self.constraint_manager.lookup_request(*args, **kwargs) - - def add_period_constraint(self, clk, period): - raise NotImplementedError - - def add_platform_command(self, *args, **kwargs): - return self.constraint_manager.add_platform_command(*args, **kwargs) - - def add_extension(self, *args, **kwargs): - return self.constraint_manager.add_extension(*args, **kwargs) - - def finalize(self, fragment, *args, **kwargs): - if self.finalized: - raise ConstraintError("Already finalized") - # if none exists, create a default clock domain and drive it - if not fragment.clock_domains: - if not hasattr(self, "default_clk_name"): - raise NotImplementedError( - "No default clock and no clock domain defined") - crg = CRG(self.request(self.default_clk_name)) - fragment += crg.get_fragment() - - self.do_finalize(fragment, *args, **kwargs) - self.finalized = True - - def do_finalize(self, fragment, *args, **kwargs): - """overload this and e.g. add_platform_command()'s after the modules - had their say""" - if hasattr(self, "default_clk_period"): - try: - self.add_period_constraint( - self.lookup_request(self.default_clk_name), - self.default_clk_period) - except ConstraintError: - pass - - def add_source(self, filename, language=None, library=None): - if language is None: - language = tools.language_by_filename(filename) - if language is None: - language = "verilog" - - if library is None: - library = "work" - - self.sources.add((os.path.abspath(filename), language, library)) - - def add_sources(self, path, *filenames, language=None, library=None): - for f in filenames: - self.add_source(os.path.join(path, f), language, library) - - def add_source_dir(self, path, recursive=True, library=None): - dir_files = [] - if recursive: - for root, dirs, files in os.walk(path): - for filename in files: - dir_files.append(os.path.join(root, filename)) - else: - for item in os.listdir(path): - if os.path.isfile(os.path.join(path, item)): - dir_files.append(os.path.join(path, item)) - for filename in dir_files: - language = tools.language_by_filename(filename) - if language is not None: - self.add_source(filename, language, library) - - def add_verilog_include_path(self, path): - self.verilog_include_paths.add(os.path.abspath(path)) - - def resolve_signals(self, vns): - # resolve signal names in constraints - sc = self.constraint_manager.get_sig_constraints() - named_sc = [(vns.get_name(sig), pins, others, resource) - for sig, pins, others, resource in sc] - # resolve signal names in platform commands - pc = self.constraint_manager.get_platform_commands() - named_pc = [] - for template, args in pc: - name_dict = dict((k, vns.get_name(sig)) for k, sig in args.items()) - named_pc.append(template.format(**name_dict)) - - return named_sc, named_pc - - def get_verilog(self, fragment, **kwargs): - return verilog.convert( - fragment, - self.constraint_manager.get_io_signals(), - create_clock_domains=False, **kwargs) - - def get_edif(self, fragment, cell_library, vendor, device, **kwargs): - return edif.convert( - fragment, - self.constraint_manager.get_io_signals(), - cell_library, vendor, device, **kwargs) - - def build(self, fragment): - raise NotImplementedError("GenericPlatform.build must be overloaded") - - def create_programmer(self): - raise NotImplementedError diff --git a/litex/gen/migen/build/lattice/__init__.py b/litex/gen/migen/build/lattice/__init__.py deleted file mode 100644 index 78b2035d..00000000 --- a/litex/gen/migen/build/lattice/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from migen.build.lattice.platform import LatticePlatform -from migen.build.lattice.programmer import LatticeProgrammer diff --git a/litex/gen/migen/build/lattice/diamond.py b/litex/gen/migen/build/lattice/diamond.py deleted file mode 100644 index 1334040b..00000000 --- a/litex/gen/migen/build/lattice/diamond.py +++ /dev/null @@ -1,105 +0,0 @@ -# This file is Copyright (c) 2015 Florent Kermarrec -# License: BSD - -import os -import sys -import subprocess -import shutil - -from migen.fhdl.structure import _Fragment - -from migen.build.generic_platform import * -from migen.build import tools -from migen.build.lattice import common - - -def _format_constraint(c): - if isinstance(c, Pins): - return ("LOCATE COMP ", " SITE " + "\"" + c.identifiers[0] + "\"") - elif isinstance(c, IOStandard): - return ("IOBUF PORT ", " IO_TYPE=" + c.name) - elif isinstance(c, Misc): - return c.misc - - -def _format_lpf(signame, pin, others, resname): - fmt_c = [_format_constraint(c) for c in ([Pins(pin)] + others)] - r = "" - for pre, suf in fmt_c: - r += pre + "\"" + signame + "\"" + suf + ";\n" - return r - - -def _build_lpf(named_sc, named_pc): - r = "BLOCK RESETPATHS;\n" - r += "BLOCK ASYNCPATHS;\n" - for sig, pins, others, resname in named_sc: - if len(pins) > 1: - for i, p in enumerate(pins): - r += _format_lpf(sig + "[" + str(i) + "]", p, others, resname) - else: - r += _format_lpf(sig, pins[0], others, resname) - if named_pc: - r += "\n" + "\n\n".join(named_pc) - return r - - -def _build_files(device, sources, vincpaths, build_name): - tcl = [] - tcl.append("prj_project new -name \"{}\" -impl \"implementation\" -dev {} -synthesis \"synplify\"".format(build_name, device)) - for path in vincpaths: - tcl.append("prj_impl option {include path} {\"" + path + "\"}") - for filename, language, library in sources: - tcl.append("prj_src add \"" + filename + "\" -work " + library) - tcl.append("prj_run Synthesis -impl implementation -forceOne") - tcl.append("prj_run Translate -impl implementation") - tcl.append("prj_run Map -impl implementation") - tcl.append("prj_run PAR -impl implementation") - tcl.append("prj_run Export -impl implementation -task Bitgen") - tools.write_to_file(build_name + ".tcl", "\n".join(tcl)) - - -def _run_diamond(build_name, source, ver=None): - if sys.platform == "win32" or sys.platform == "cygwin": - build_script_contents = "REM Autogenerated by Migen\n" - build_script_contents = "pnmainc " + build_name + ".tcl\n" - build_script_file = "build_" + build_name + ".bat" - tools.write_to_file(build_script_file, build_script_contents) - r = subprocess.call([build_script_file]) - shutil.copy(os.path.join("implementation", build_name + "_implementation.bit"), build_name + ".bit") - else: - raise NotImplementedError - - if r != 0: - raise OSError("Subprocess failed") - - -class LatticeDiamondToolchain: - def build(self, platform, fragment, build_dir="build", build_name="top", - toolchain_path="/opt/Diamond", run=True): - tools.mkdir_noerror(build_dir) - os.chdir(build_dir) - - if not isinstance(fragment, _Fragment): - fragment = fragment.get_fragment() - platform.finalize(fragment) - - v_output = platform.get_verilog(fragment) - named_sc, named_pc = platform.resolve_signals(v_output.ns) - v_file = build_name + ".v" - v_output.write(v_file) - sources = platform.sources | {(v_file, "verilog", "work")} - _build_files(platform.device, sources, platform.verilog_include_paths, build_name) - - tools.write_to_file(build_name + ".lpf", _build_lpf(named_sc, named_pc)) - - if run: - _run_diamond(build_name, toolchain_path) - - os.chdir("..") - - return v_output.ns - - def add_period_constraint(self, platform, clk, period): - # TODO: handle differential clk - platform.add_platform_command("""FREQUENCY PORT "{clk}" {freq} MHz;""".format(freq=str(float(1/period)*1000), clk="{clk}"), clk=clk) diff --git a/litex/gen/migen/build/lattice/platform.py b/litex/gen/migen/build/lattice/platform.py deleted file mode 100644 index 73742231..00000000 --- a/litex/gen/migen/build/lattice/platform.py +++ /dev/null @@ -1,26 +0,0 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.lattice import common, diamond - - -class LatticePlatform(GenericPlatform): - bitstream_ext = ".bit" - - def __init__(self, *args, toolchain="diamond", **kwargs): - GenericPlatform.__init__(self, *args, **kwargs) - if toolchain == "diamond": - self.toolchain = diamond.LatticeDiamondToolchain() - else: - raise ValueError("Unknown toolchain") - - def get_verilog(self, *args, special_overrides=dict(), **kwargs): - so = dict(common.lattice_special_overrides) - so.update(special_overrides) - return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs) - - def build(self, *args, **kwargs): - return self.toolchain.build(self, *args, **kwargs) - - def add_period_constraint(self, clk, period): - if hasattr(clk, "p"): - clk = clk.p - self.toolchain.add_period_constraint(self, clk, period) diff --git a/litex/gen/migen/build/platforms/apf27.py b/litex/gen/migen/build/platforms/apf27.py deleted file mode 100644 index ea182e21..00000000 --- a/litex/gen/migen/build/platforms/apf27.py +++ /dev/null @@ -1,150 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_ios = [ - ("clk0", 0, Pins("N9"), IOStandard("LVCMOS18")), - ("fpga_reset", 0, Pins("T9"), IOStandard("LVCMOS18"), Drive("8")), - ("fpga_initb", 0, Pins("T12"), IOStandard("LVCMOS18"), Drive("8")), - ("weim", 0, - Subsignal("cs4_dtack", Pins("R3"), IOStandard("LVCMOS18"), Drive("8")), - Subsignal("cs5n", Pins("P10"), IOStandard("LVCMOS18")), - Subsignal("eb0n", Pins("P9"), IOStandard("LVCMOS18")), - Subsignal("oen", Pins("R9"), IOStandard("LVCMOS18")), - Subsignal("data", - Pins("T5 T6 P7 N8 P12 T13 R13 T14 P5 N6 T3 T11 T4 R5 M10 T10"), - IOStandard("LVCMOS18"), Drive("8")), - Subsignal("addr", - Pins("N5 L7 M7 M8 L8 L9 L10 M11 P11 N11 N12 P13"), - IOStandard("LVCMOS18")) - ) -] - -_connectors = [ - ("J2", - "None", # no 0 pin - "None", # 1 +3v3 - "None", # 2 +3v3 - "None", # 3 GND - "None", # 4 GND - "None", # 5 DP USB_OTG_PHY +3V3 - "None", # 6 DM USB_OTG_PHY +3V3 - "None", # 7 VBUS USB_OTG_ PHY +3V3 - "None", # 8 PSW_N USB_OTG_PHY +3V3 - "None", # 9 ID USB_OTG_PHY +3V3 - "None", # 10 FAULT USB_OTG_PHY +3V3 - "None", # 11 RXP Ethernet_PHY +3V3 - "None", # 12 RXN Ethernet_PHY +3V3 - "None", # 13 ETH_LINK Ethernet_PHY +2V8 - "None", # 14 PC_VS2 PC +2V8 PF13 - "None", # 15 PC_VS1 PC +2V8 PF14 - "None", # 16 PC_PWRON PC +2V8 PF16 - "None", # 17 PC_READY PC +2V8 PF17 - "None", # 18 PWM0 PWM0 +2V8 PE5 - "None", # 19 TOUT GPT +2V8 PC14 - "None", # 20 GND POWER - "None", # 21 VCC01 (IN) BANK1 SUPPLY VCCO1 - "C16", # 22 IO_L24P_1 FPGA_BANK1 VCC01 - "C15", # 23 IO_L24N_1 FPGA_BANK1 VCC01 - "D16", # 24 IO_L22_P1 FPGA_BANK1 VCC01 - "None", # 25 GND POWER - "B14", # 26 IO_L02N_0 FPGA_BANK0 VCCO0 - "B15", # 27 IO_L02P_0 FPGA_BANK0 - "A13", # 28 IO_L04N_0 FPGA_BANK0 - "A14", # 29 IO_L04P_0 FPGA_BANK0 VCCO0 - "D11", # 30 IO_L03N_0 FPGA_BANK0 VCCO0 - "C12", # 31 IO_L03P_0 FPGA_BANK0 VCCO0 - "A10", # 32 IO_L08N_0 FPGA_BANK0 VCCO0 - "B10", # 33 IO_L08P_0 FPGA_BANK0 VCCO0 - "A9", # 34 IO_L10N_0 / GLCK7 FPGA_BANK0 VCCO0 - "C9", # 35 IO_L10P_0 / GCLK6 FPGA_BANK0 VCCO0 - "B8", # 36 IO_L12N_0 / GCLK11 FPGA_BANK0 VCCO0 - "A8", # 37 IO_L12P_0 / GCLK10 FPGA_BANK0 VCCO0 - "B6", # 38 IO_L15N_0 FPGA_BANK0 VCCO0 - "A6", # 39 IO_L15P_0 FPGA_BANK0 VCCO0 - "B4", # 40 IO_L18N_0 FPGA_BANK0 VCCO0 - "A4", # 41 IO_L18P_0 FPGA_BANK0 VCCO0 - "None", # 42 GND POWER - "N3", # 43 IO_L24P_3 FPGA_BANK3 VCCO3 - "R1", # 44 IO_L23P_3 FPGA_BANK3 VCCO3 - "P1", # 45 IO_L22N_3 FPGA_BANK3 VCCO3 - "N1", # 46 IO_L20N_3 FPGA_BANK3 VCCO3 - "M1", # 47 IO_L20P_3 FPGA_BANK3 VCCO3 - "H3", # 48 IO_L12P_3 FPGA_BANK3 VCCO3 - "K1", # 49 IO_L15N_3 FPGA_BANK3 VCCO3 - "J1", # 50 IO_L14N_3 FPGA_BANK3 VCCO3 - "H1", # 51 IO_L11N_3 FPGA_BANK3 VCCO3 - "G1", # 52 IO_L08N_3 FPGA_BANK3 VCCO3 - "F1", # 53 IO_L08P_3 FPGA_BANK3 VCCO3 - "E1", # 54 IO_L03N_3 FPGA_BANK3 VCCO3 - "D1", # 55 IO_LO3P_3 FPGA_BANK3 VCCO3 - "C1", # 56 IO_L01N_3 FPGA_BANK3 VCCO3 - "None", # 57 GND POWER - "None", # 58 TRSTN JTAG +2V8 - "None", # 59 TDI JTAG +2V8 - "None", # 60 TCK JTAG +2V8 - "None", # 61 TDO JTAG +2V8 - "None", # 62 TMS JTAG +2V8 - "None", # 63 GND POWER - "C2", # 64 IO_L01P_3 FPGA_BANK3 VCCO3 - "D3", # 65 IO_L02N_3 FPGA_BANK3 VCCO3 - "D4", # 66 IO_L02P_3 FPGA_BANK3 VCCO3 - "F4", # 67 IP_LO4N_3 FPGA_BANK3 VCCO3 - "G2", # 68 IO_L11P_3 FPGA_BANK3 VCCO3 - "J2", # 69 IO_L14P_3 FPGA_BANK3 VCCO3 - "K3", # 70 IO_L15P_3 FPGA_BANK3 VCCO3 - "J3", # 71 IO_L12N_3 FPGA_BANK3 VCCO3 - "N2", # 72 IO_L22P_3 FPGA_BANK3 VCCO3 - "P2", # 73 IO_L23N_3 FPGA_BANK3 VCCO3 - "M4", # 74 IO_L24N_3 FPGA_BANK3 VCCO3 - "L6", # 75 IP_L25N_3 FPGA_BANK3 VCCO3 - "None", # 76 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax) - "None", # 77 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax) - "A3", # 78 IO_L19P_0 FPGA_BANK0 VCCO0 - "B3", # 79 IO_L19N_0 FPGA_BANK0 VCCO0 - "A5", # 80 IO_L17P_0 FPGA_BANK0 VCCO0 - "C5", # 81 IO_L17N_0 FPGA_BANK0 VCCO0 - "D7", # 82 IO_L16P_0 FPGA_BANK0 VCCO0 - "C6", # 83 IO_L16N_0 FPGA_BANK0 VCCO0 - "C8", # 84 IO_L11P_0 / GCLK8 FPGA_BANK0 VCCO0 - "D8", # 85 IO_L11N_0 / GCLK9 FPGA_BANK0 VCCO0 - "C10", # 86 IO_L09P_0 / GCLK4 FPGA_BANK0 VCCO0 - "D9", # 87 IO_L09N_0 / GCLK5 FPGA_BANK0 VCCO0 - "C11", # 88 IO_L07P_0 FPGA_BANK0 VCCO0 - "A11", # 89 IO_L07N_0 FPGA_BANK0 VCCO0 - "D13", # 90 IO_L01P_0 FPGA_BANK0 VCCO0 - "C13", # 91 IO_L01N_0 FPGA_BANK0 VCCO0 - "None", # 92 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax) - "None", # 93 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax) - "None", # 94 GND POWER VCCO0 A13 - "D15", # 95 IO_L22N_1 FPGA_BANK1 VCC01 - "E13", # 96 IO_L23P_1 FPGA_BANK1 VCC01 - "D14", # 97 IO_L23N_1 FPGA_BANK1 VCC01 - "E14", # 98 IO_L20P_1 FPGA_BANK1 VCC01 - "F13", # 99 IO_L20N_1 FPGA_BANK1 VCC01 - "None", # 100 GND POWER (3.3Vmax) - "None", # 101 USR_RESETN (open CONFIG Pos PC15 +2V8 drain with pullup) - "None", # 102 TIN GPT +2V8 - "None", # 103 EXTAL_26M CONFIG +2V5 - "None", # 104 RX3 RS232_3 RS232 - "None", # 105 TX3 RS232_3 RS232 - "None", # 106 RX1 RS232_1 RS232 - "None", # 107 TX1 RS232_1 RS232 - "None", # 108 BOOT CONFIG +2V8 - "None", # 109 TXN Ethernet_PHY +3V3 - "None", # 110 TXP Ethernet_PHY +3V3 - "None", # 111 ETH_ACTIVITY Ethernet_PHY +2V8 - "None", # 112 USBH2_NXT USB_HOST2 +2V5 PA3 - "None", # 113 USBH2_DIR USB_HOST2 +2V5 PA1 - "None", # 114 USBH2_DATA7 USB_HOST2 +2V5 PA2 - "None", # 115 USBH2_STP USB_HOST2 +2V5 PA4 - "None") # 116 USBH2_CLK USB_HOST2 +2V5 PA0 -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk0" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc3s200a-ft256-4", _ios, _connectors) diff --git a/litex/gen/migen/build/platforms/apf51.py b/litex/gen/migen/build/platforms/apf51.py deleted file mode 100644 index f776cdac..00000000 --- a/litex/gen/migen/build/platforms/apf51.py +++ /dev/null @@ -1,177 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_ios = [ - ("clk3", 0, Pins("N8"), IOStandard("LVCMOS33")), - ("clko", 0, Pins("N7"), IOStandard("LVCMOS33")), - ("fpga_initb", 0, Pins("P3"), IOStandard("LVCMOS33")), - ("fpga_program", 0, Pins("R2"), IOStandard("LVCMOS33")), - ("eim", 0, - Subsignal("bclk", Pins("N12")), - Subsignal("eb1", Pins("P13")), - Subsignal("cs1", Pins("R11")), - Subsignal("cs2", Pins("N9")), - Subsignal("lba", Pins("R9")), - Subsignal("eb0", Pins("P7")), - Subsignal("oe", Pins("R7")), - Subsignal("rw", Pins("R6")), - Subsignal("dtack", Pins("N4")), - Subsignal("wait", Pins("R4")), - Subsignal("da", Pins("N6 L5 L6 R5 P5 N11 M11 P11 L8 K8 M8 M10 L9 R10 N5 M5")), - IOStandard("LVCMOS33") - ) -] - -_connectors = [ - ("J2", - "None", # No 0 pin - "None", # 1 FPGA Bank1 power - "None", # 2 FPGA Bank1 power - "None", # 3 GND - "B14", # 4 IO_L1P_A25_1 - "B15", # 5 IO_L1N_A24_VREF_1 - "C14", # 6 IO_L33P_A15_M1A10_1 - "C15", # 7 IO_L33N_A14_M1A4_1 - "D13", # 8 IO_L35P_A11_M1A7_1 - "D15", # 9 IO_L35N_A10_M1A2_1 - "E14", # 10 IO_L37P_A7_M1A0_1 - "E15", # 11 IO_L37N_A6_M1A1_1 - "None", # 12 GND - "F13", # 13 IO_L39P_M1A3_1 - "F15", # 14 IO_L39N_M1ODT_1 - "G14", # 15 IO_L41P_GCLK9_IRDY1_M1RASN_1 - "G15", # 16 IO_L41N_GCLK8_M1CASN_1 - "H13", # 17 IO_L42P_GCLK7_M1UDM_1 - "H15", # 18 IO_L42N_GCLK6_TRDY1_M1LDM - "J14", # 19 IO_L43P_GCLK5_M1DQ4_1 - "J15", # 20 IO_L43N_GCLK4_M1DQ5_1 - "K13", # 21 IO_L44P_A3_M1DQ6_1 - "K15", # 22 IO_L44N_A2_M1DQ7_1 - "L14", # 23 IO_L45P_A1_M1LDQS_1 - "L15", # 24 IO_L45N_A0_M1LDQSN_1 - "None", # 25 GND - "E2", # 26 IO_L52P_M3A8_3 - "E1", # 27 IO_L52N_M3A9_3 - "D3", # 28 IO_L54P_M3RESET_3 - "D1", # 29 IO_L54N_M3A11_3 - "F3", # 30 IO_L46P_M3CLK_3 - "F1", # 31 IO_L46N_M3CLKN_3 - "G2", # 32 IO_L44P_GCLK21_M3A5_3 - "G1", # 33 IO_L44N_GCLK20_M3A6_3 - "H3", # 34 IO_L42P_GCLK25_TRDY2_M3UDM_3 - "H1", # 35 IO_L42N_GCLK24_M3LDM_3 - "K3", # 36 IO_L40P_M3DQ6_3 - "K1", # 37 IO_L40N_M3DQ7_3 - "None", # 38 GND - "None", # 39 GPIO4_16 - "None", # 40 GPIO4_17 - "None", # 41 BOOT_MODE0 - "None", # 42 AUD5_RXFS - "None", # 43 AUD5_RXC - "None", # 44 GND - "None", # 45 AUD5_RXD - "None", # 46 AUD5_TXC - "None", # 47 AUD5_TXFS - "None", # 48 GND - "None", # 49 SPI2_SCLK_GPT_CMPOUT3 - "None", # 50 SPI2_MISO - "None", # 51 SPI2_MOSI - "None", # 52 SPI2_SS1 - "None", # 53 SPI2_SS2 - "None", # 54 SPI2_SS3 - "None", # 55 SPI2_RDY - "None", # 56 OWIRE - "None", # 57 GND - "None", # 58 SPI1_SCLK - "None", # 59 SPI1_MISO - "None", # 60 SPI1_MOSI - "None", # 61 SPI1_SS0 - "None", # 62 SPI1_SS1 - "None", # 63 SPI1_RDY - "None", # 64 RESET# - "None", # 65 VIO_H2 - "None", # 66 PMIC_GPIO6 - "None", # 67 TOUCH_X+ - "None", # 68 TOUCH_X- - "None", # 69 TOUCH_Y+ - "None", # 70 TOUCH_Y- - "None", # 71 AUXADCIN4 - "None", # 72 AUXADCIN3 - "None", # 73 AUXADCIN2 - "None", # 74 AUXADCIN1 - "None", # 75 PMIC_GPIO7 - "None", # 76 +1v8 - "None", # 77 RESERVED - "None", # 78 UART3_TXD - "None", # 79 UART_3_RXD - "None", # 80 UART2_TXD - "None", # 81 UART2_RXD - "None", # 82 UART2_RTS_KEY_COL7 - "None", # 83 UART2_CTS_KEY_COL6 - "None", # 84 UART1_TXD - "None", # 85 UART1_RXD - "None", # 86 UART1_RTS - "None", # 87 UART1_CTS - "None", # 88 GND - "None", # 89 AUD3_TXD - "None", # 90 AUD3_RXD - "None", # 91 AUD3_FS - "None", # 92 AUD3_CK - "None", # 93 GND - "None", # 94 AUD6_TXFS_KEY_ROW7 - "None", # 95 AUD6_TXC_KEY_ROW6 - "None", # 96 AUD6_RXD_KEY_ROW5 - "None", # 97 AUD6_TXD_KEY_ROW4 - "None", # 98 I2C2_SDA_UART3_CTS - "None", # 99 I2C2_SCL_UART3_RTS - "None", # 100 BOOT_MODE1 - "None", # 101 PWM2 - "None", # 102 PWM1 - "None", # 103 GND - "L1", # 104 IO_L39N_M3LDQSN_3 - "L2", # 105 IO_L39P_M3LDQS_3 - "J1", # 106 IO_L41N_GCLK26_M3DQ5_3 - "J2", # 107 IO_L41P_GCLK27_M3DQ4_3 - "J3", # 108 IO_L43N_GCLK22_IRDY2_M3CASN_3 - "K4", # 109 IO_L43P_GCLK23_M3RASN_3 - "J4", # 110 IO_L45N_M3ODT_3 - "K5", # 111 IO_L45P_M3A3_3 - "C1", # 112 IO_L83N_VREF_3 - "C2", # 113 IO_L83P_3 - "E3", # 114 IO_L53N_M3A12_3 - "D4", # 115 IO_L53P_M3CKE_3 - "None", # 116 GND - "P15", # 117 IO_L74N_DOUT_BUSY_1 - "P14", # 118 IO_L74P_AWAKE_1 - "N15", # 119 IO_L47N_LDC_M1DQ1_1 - "N14", # 120 IO_L47P_FWE_B_M1DQ0_1 - "M15", # 121 IO_L46N_FOE_B_M1DQ3_1 - "M13", # 122 IO_L46P_FCS_B_M1DQS2_1 - "L12", # 123 IO_L40N_GCLK10_M1A6_1 - "K12", # 124 IO_L40P_GCLK11_M1A5_1 - "K11", # 125 IO_L38N_A4_M1CLKN_1 - "K10", # 126 IO_L38P_A5_M1CLK_1 - "J13", # 127 IO_L36N_A8_M1BA1_1 - "J11", # 128 IO_L36P_A9_M1BA0_1 - "None", # 129 GND - "G13", # 130 IO_L34N_A12_M1BA2_1_NOTLX4 - "H12", # 131 IO_L34P_A13_M1WE_1_NOTLX4 - "H11", # 132 IO_L32N_A16_M1A9_1_NOTLX4 - "H10", # 133 IO_L32P_A17_M1A8_1_NOTLX4 - "F12", # 134 IO_L31N_A18_M1A12_1_NOTLX4 - "F11", # 135 IO_L31P_A19_M1CKE_1_NOTLX4 - "G12", # 136 IO_L30N_A20_M1A11_1_NOTLX4 - "G11", # 137 IO_L30P_A21_M1RESET_1_NOTLX4 - "None", # 138 GND - "None", # 139 FPGA_BANK3_POWER - "None") # 140 FPGA_BANK3_POWER -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk3" - default_clk_period = 10.526 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-2csg225", _ios, _connectors) diff --git a/litex/gen/migen/build/platforms/kc705.py b/litex/gen/migen/build/platforms/kc705.py deleted file mode 100644 index eb51ab33..00000000 --- a/litex/gen/migen/build/platforms/kc705.py +++ /dev/null @@ -1,458 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform, XC3SProg, VivadoProgrammer, iMPACT -from migen.build.xilinx.ise import XilinxISEToolchain - - -_io = [ - ("user_led", 0, Pins("AB8"), IOStandard("LVCMOS15")), - ("user_led", 1, Pins("AA8"), IOStandard("LVCMOS15")), - ("user_led", 2, Pins("AC9"), IOStandard("LVCMOS15")), - ("user_led", 3, Pins("AB9"), IOStandard("LVCMOS15")), - ("user_led", 4, Pins("AE26"), IOStandard("LVCMOS25")), - ("user_led", 5, Pins("G19"), IOStandard("LVCMOS25")), - ("user_led", 6, Pins("E18"), IOStandard("LVCMOS25")), - ("user_led", 7, Pins("F16"), IOStandard("LVCMOS25")), - - ("cpu_reset", 0, Pins("AB7"), IOStandard("LVCMOS15")), - - ("user_btn_c", 0, Pins("G12"), IOStandard("LVCMOS25")), - ("user_btn_n", 0, Pins("AA12"), IOStandard("LVCMOS15")), - ("user_btn_s", 0, Pins("AB12"), IOStandard("LVCMOS15")), - ("user_btn_w", 0, Pins("AC6"), IOStandard("LVCMOS15")), - ("user_btn_e", 0, Pins("AG5"), IOStandard("LVCMOS15")), - - ("user_dip_btn", 0, Pins("Y29"), IOStandard("LVCMOS25")), - ("user_dip_btn", 1, Pins("W29"), IOStandard("LVCMOS25")), - ("user_dip_btn", 2, Pins("AA28"), IOStandard("LVCMOS25")), - ("user_dip_btn", 3, Pins("Y28"), IOStandard("LVCMOS25")), - - ("user_sma_clock", 0, - Subsignal("p", Pins("L25"), IOStandard("LVDS_25")), - Subsignal("n", Pins("K25"), IOStandard("LVDS_25")) - ), - ("user_sma_clock_p", 0, Pins("L25"), IOStandard("LVCMOS25")), - ("user_sma_clock_n", 0, Pins("K25"), IOStandard("LVCMOS25")), - - ("user_sma_gpio_p", 0, Pins("Y23"), IOStandard("LVCMOS33")), - ("user_sma_gpio_n", 0, Pins("Y24"), IOStandard("LVCMOS33")), - - ("clk200", 0, - Subsignal("p", Pins("AD12"), IOStandard("LVDS")), - Subsignal("n", Pins("AD11"), IOStandard("LVDS")) - ), - - ("clk156", 0, - Subsignal("p", Pins("K28"), IOStandard("LVDS_25")), - Subsignal("n", Pins("K29"), IOStandard("LVDS_25")) - ), - - ("i2c", 0, - Subsignal("scl", Pins("K21")), - Subsignal("sda", Pins("L21")), - IOStandard("LVCMOS25")), - - ("serial", 0, - Subsignal("cts", Pins("L27")), - Subsignal("rts", Pins("K23")), - Subsignal("tx", Pins("K24")), - Subsignal("rx", Pins("M19")), - IOStandard("LVCMOS25")), - - ("spiflash", 0, # clock needs to be accessed through STARTUPE2 - Subsignal("cs_n", Pins("U19")), - Subsignal("dq", Pins("P24", "R25", "R20", "R21")), - IOStandard("LVCMOS25") - ), - - ("mmc", 0, - Subsignal("wp", Pins("Y21")), - Subsignal("det", Pins("AA21")), - Subsignal("cmd", Pins("AB22")), - Subsignal("clk", Pins("AB23")), - Subsignal("dat", Pins("AC20 AA23 AA22 AC21")), - IOStandard("LVCMOS25")), - - ("lcd", 0, - Subsignal("db", Pins("AA13 AA10 AA11 Y10")), - Subsignal("e", Pins("AB10")), - Subsignal("rs", Pins("Y11")), - Subsignal("rw", Pins("AB13")), - IOStandard("LVCMOS15")), - - ("rotary", 0, - Subsignal("a", Pins("Y26")), - Subsignal("b", Pins("Y25")), - Subsignal("push", Pins("AA26")), - IOStandard("LVCMOS25")), - - ("hdmi", 0, - Subsignal("d", Pins("B23 A23 E23 D23 F25 E25 E24 D24 F26 E26 G23 G24 J19 H19 L17 L18 K19 K20")), - Subsignal("de", Pins("H17")), - Subsignal("clk", Pins("K18")), - Subsignal("vsync", Pins("H20")), - Subsignal("hsync", Pins("J18")), - Subsignal("int", Pins("AH24")), - Subsignal("spdif", Pins("J17")), - Subsignal("spdif_out", Pins("G20")), - IOStandard("LVCMOS25")), - - ("ddram", 0, - Subsignal("a", Pins( - "AH12 AG13 AG12 AF12 AJ12 AJ13 AJ14 AH14", - "AK13 AK14 AF13 AE13 AJ11 AH11 AK10 AK11"), - IOStandard("SSTL15")), - Subsignal("ba", Pins("AH9 AG9 AK9"), IOStandard("SSTL15")), - Subsignal("ras_n", Pins("AD9"), IOStandard("SSTL15")), - Subsignal("cas_n", Pins("AC11"), IOStandard("SSTL15")), - Subsignal("we_n", Pins("AE9"), IOStandard("SSTL15")), - Subsignal("cs_n", Pins("AC12"), IOStandard("SSTL15")), - Subsignal("dm", Pins("Y16 AB17 AF17 AE16 AK5 AJ3 AF6 AC7"), - IOStandard("SSTL15")), - Subsignal("dq", Pins( - "AA15 AA16 AC14 AD14 AA17 AB15 AE15 Y15", - "AB19 AD16 AC19 AD17 AA18 AB18 AE18 AD18", - "AG19 AK19 AG18 AF18 AH19 AJ19 AE19 AD19", - "AK16 AJ17 AG15 AF15 AH17 AG14 AH15 AK15", - "AK8 AK6 AG7 AF7 AF8 AK4 AJ8 AJ6", - "AH5 AH6 AJ2 AH2 AH4 AJ4 AK1 AJ1", - "AF1 AF2 AE4 AE3 AF3 AF5 AE1 AE5", - "AC1 AD3 AC4 AC5 AE6 AD6 AC2 AD4"), - IOStandard("SSTL15_T_DCI")), - Subsignal("dqs_p", Pins("AC16 Y19 AJ18 AH16 AH7 AG2 AG4 AD2"), - IOStandard("DIFF_SSTL15")), - Subsignal("dqs_n", Pins("AC15 Y18 AK18 AJ16 AJ7 AH1 AG3 AD1"), - IOStandard("DIFF_SSTL15")), - Subsignal("clk_p", Pins("AG10"), IOStandard("DIFF_SSTL15")), - Subsignal("clk_n", Pins("AH10"), IOStandard("DIFF_SSTL15")), - Subsignal("cke", Pins("AF10"), IOStandard("SSTL15")), - Subsignal("odt", Pins("AD8"), IOStandard("SSTL15")), - Subsignal("reset_n", Pins("AK3"), IOStandard("LVCMOS15")), - Misc("SLEW=FAST"), - Misc("VCCAUX_IO=HIGH") - ), - - ("eth_clocks", 0, - Subsignal("tx", Pins("M28")), - Subsignal("gtx", Pins("K30")), - Subsignal("rx", Pins("U27")), - IOStandard("LVCMOS25") - ), - ("eth", 0, - Subsignal("rst_n", Pins("L20")), - Subsignal("int_n", Pins("N30")), - Subsignal("mdio", Pins("J21")), - Subsignal("mdc", Pins("R23")), - Subsignal("dv", Pins("R28")), - Subsignal("rx_er", Pins("V26")), - Subsignal("rx_data", Pins("U30 U25 T25 U28 R19 T27 T26 T28")), - Subsignal("tx_en", Pins("M27")), - Subsignal("tx_er", Pins("N29")), - Subsignal("tx_data", Pins("N27 N25 M29 L28 J26 K26 L30 J28")), - Subsignal("col", Pins("W19")), - Subsignal("crs", Pins("R30")), - IOStandard("LVCMOS25") - ), - - ("pcie_x1", 0, - Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")), - Subsignal("clk_p", Pins("U8")), - Subsignal("clk_n", Pins("U7")), - Subsignal("rx_p", Pins("M6")), - Subsignal("rx_n", Pins("M5")), - Subsignal("tx_p", Pins("L4")), - Subsignal("tx_n", Pins("L3")) - ), - ("pcie_x2", 0, - Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")), - Subsignal("clk_p", Pins("U8")), - Subsignal("clk_n", Pins("U7")), - Subsignal("rx_p", Pins("M6 P6")), - Subsignal("rx_n", Pins("M5 P5")), - Subsignal("tx_p", Pins("L4 M2")), - Subsignal("tx_n", Pins("L3 M1")) - ), - ("pcie_x4", 0, - Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")), - Subsignal("clk_p", Pins("U8")), - Subsignal("clk_n", Pins("U7")), - Subsignal("rx_p", Pins("M6 P6 R4 T6")), - Subsignal("rx_n", Pins("M5 P5 R3 T5")), - Subsignal("tx_p", Pins("L4 M2 N4 P2")), - Subsignal("tx_n", Pins("L3 M1 N3 P1")) - ), - ("pcie_x8", 0, - Subsignal("rst_n", Pins("G25"), IOStandard("LVCMOS25")), - Subsignal("clk_p", Pins("U8")), - Subsignal("clk_n", Pins("U7")), - Subsignal("rx_p", Pins("M6 P6 R4 T6 V6 W4 Y6 AA4")), - Subsignal("rx_n", Pins("M5 P5 R3 T5 V5 W3 Y5 AA3")), - Subsignal("tx_p", Pins("L4 M2 N4 P2 T2 U4 V2 Y2")), - Subsignal("tx_n", Pins("L3 M1 N3 P1 T1 U3 V1 Y1")) - ) -] - -_connectors = [ - ("HPC", { - "DP1_M2C_P": "D6", - "DP1_M2C_N": "D5", - "DP2_M2C_P": "B6", - "DP2_M2C_N": "B5", - "DP3_M2C_P": "A8", - "DP3_M2C_N": "A7", - "DP1_C2M_P": "C4", - "DP1_C2M_N": "C3", - "DP2_C2M_P": "B2", - "DP2_C2M_N": "B1", - "DP3_C2M_P": "A4", - "DP3_C2M_N": "A3", - "DP0_C2M_P": "D2", - "DP0_C2M_N": "D1", - "DP0_M2C_P": "E4", - "DP0_M2C_N": "E3", - "LA06_P": "H30", - "LA06_N": "G30", - "LA10_P": "D29", - "LA10_N": "C30", - "LA14_P": "B28", - "LA14_N": "A28", - "LA18_CC_P": "F21", - "LA18_CC_N": "E21", - "LA27_P": "C19", - "LA27_N": "B19", - "HA01_CC_P": "H14", - "HA01_CC_N": "G14", - "HA05_P": "F15", - "HA05_N": "E16", - "HA09_P": "F12", - "HA09_N": "E13", - "HA13_P": "L16", - "HA13_N": "K16", - "HA16_P": "L15", - "HA16_N": "K15", - "HA20_P": "K13", - "HA20_N": "J13", - "CLK1_M2C_P": "D17", - "CLK1_M2C_N": "D18", - "LA00_CC_P": "C25", - "LA00_CC_N": "B25", - "LA03_P": "H26", - "LA03_N": "H27", - "LA08_P": "E29", - "LA08_N": "E30", - "LA12_P": "C29", - "LA12_N": "B29", - "LA16_P": "B27", - "LA16_N": "A27", - "LA20_P": "E19", - "LA20_N": "D19", - "LA22_P": "C20", - "LA22_N": "B20", - "LA25_P": "G17", - "LA25_N": "F17", - "LA29_P": "C17", - "LA29_N": "B17", - "LA31_P": "G22", - "LA31_N": "F22", - "LA33_P": "H21", - "LA33_N": "H22", - "HA03_P": "C12", - "HA03_N": "B12", - "HA07_P": "B14", - "HA07_N": "A15", - "HA11_P": "B13", - "HA11_N": "A13", - "HA14_P": "J16", - "HA14_N": "H16", - "HA18_P": "K14", - "HA18_N": "J14", - "HA22_P": "L11", - "HA22_N": "K11", - "GBTCLK1_M2C_P": "E8", - "GBTCLK1_M2C_N": "E7", - "GBTCLK0_M2C_P": "C8", - "GBTCLK0_M2C_N": "C7", - "LA01_CC_P": "D26", - "LA01_CC_N": "C26", - "LA05_P": "G29", - "LA05_N": "F30", - "LA09_P": "B30", - "LA09_N": "A30", - "LA13_P": "A25", - "LA13_N": "A26", - "LA17_CC_P": "F20", - "LA17_CC_N": "E20", - "LA23_P": "B22", - "LA23_N": "A22", - "LA26_P": "B18", - "LA26_N": "A18", - "PG_M2C": "J29", - "HA00_CC_P": "D12", - "HA00_CC_N": "D13", - "HA04_P": "F11", - "HA04_N": "E11", - "HA08_P": "E14", - "HA08_N": "E15", - "HA12_P": "C15", - "HA12_N": "B15", - "HA15_P": "H15", - "HA15_N": "G15", - "HA19_P": "H11", - "HA19_N": "H12", - "PRSNT_M2C_B": "M20", - "CLK0_M2C_P": "D27", - "CLK0_M2C_N": "C27", - "LA02_P": "H24", - "LA02_N": "H25", - "LA04_P": "G28", - "LA04_N": "F28", - "LA07_P": "E28", - "LA07_N": "D28", - "LA11_P": "G27", - "LA11_N": "F27", - "LA15_P": "C24", - "LA15_N": "B24", - "LA19_P": "G18", - "LA19_N": "F18", - "LA21_P": "A20", - "LA21_N": "A21", - "LA24_P": "A16", - "LA24_N": "A17", - "LA28_P": "D16", - "LA28_N": "C16", - "LA30_P": "D22", - "LA30_N": "C22", - "LA32_P": "D21", - "LA32_N": "C21", - "HA02_P": "D11", - "HA02_N": "C11", - "HA06_P": "D14", - "HA06_N": "C14", - "HA10_P": "A11", - "HA10_N": "A12", - "HA17_CC_P": "G13", - "HA17_CC_N": "F13", - "HA21_P": "J11", - "HA21_N": "J12", - "HA23_P": "L12", - "HA23_N": "L13", - } - ), - ("LPC", { - "GBTCLK0_M2C_P": "N8", - "GBTCLK0_M2C_N": "N7", - "LA01_CC_P": "AE23", - "LA01_CC_N": "AF23", - "LA05_P": "AG22", - "LA05_N": "AH22", - "LA09_P": "AK23", - "LA09_N": "AK24", - "LA13_P": "AB24", - "LA13_N": "AC25", - "LA17_CC_P": "AB27", - "LA17_CC_N": "AC27", - "LA23_P": "AH26", - "LA23_N": "AH27", - "LA26_P": "AK29", - "LA26_N": "AK30", - "CLK0_M2C_P": "AF22", - "CLK0_M2C_N": "AG23", - "LA02_P": "AF20", - "LA02_N": "AF21", - "LA04_P": "AH21", - "LA04_N": "AJ21", - "LA07_P": "AG25", - "LA07_N": "AH25", - "LA11_P": "AE25", - "LA11_N": "AF25", - "LA15_P": "AC24", - "LA15_N": "AD24", - "LA19_P": "AJ26", - "LA19_N": "AK26", - "LA21_P": "AG27", - "LA21_N": "AG28", - "LA24_P": "AG30", - "LA24_N": "AH30", - "LA28_P": "AE30", - "LA28_N": "AF30", - "LA30_P": "AB29", - "LA30_N": "AB30", - "LA32_P": "Y30", - "LA32_N": "AA30", - "LA06_P": "AK20", - "LA06_N": "AK21", - "LA10_P": "AJ24", - "LA10_N": "AK25", - "LA14_P": "AD21", - "LA14_N": "AE21", - "LA18_CC_P": "AD27", - "LA18_CC_N": "AD28", - "LA27_P": "AJ28", - "LA27_N": "AJ29", - "CLK1_M2C_P": "AG29", - "CLK1_M2C_N": "AH29", - "LA00_CC_P": "AD23", - "LA00_CC_N": "AE24", - "LA03_P": "AG20", - "LA03_N": "AH20", - "LA08_P": "AJ22", - "LA08_N": "AJ23", - "LA12_P": "AA20", - "LA12_N": "AB20", - "LA16_P": "AC22", - "LA16_N": "AD22", - "LA20_P": "AF26", - "LA20_N": "AF27", - "LA22_P": "AJ27", - "LA22_N": "AK28", - "LA25_P": "AC26", - "LA25_N": "AD26", - "LA29_P": "AE28", - "LA29_N": "AF28", - "LA31_P": "AD29", - "LA31_N": "AE29", - "LA33_P": "AC29", - "LA33_N": "AC30", - } - ) -] - - -class Platform(XilinxPlatform): - identifier = 0x4B37 - default_clk_name = "clk156" - default_clk_period = 6.4 - - def __init__(self, toolchain="vivado", programmer="xc3sprog"): - XilinxPlatform.__init__(self, "xc7k325t-ffg900-2", _io, _connectors, - toolchain=toolchain) - if toolchain == "ise": - self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g ConfigRate:12 -g SPI_buswidth:4" - elif toolchain == "vivado": - self.toolchain.bitstream_commands = ["set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design]"] - self.toolchain.additional_commands = ["write_cfgmem -force -format bin -interface spix4 -size 16 -loadbit \"up 0x0 {build_name}.bit\" -file {build_name}.bin"] - self.programmer = programmer - - def create_programmer(self): - if self.programmer == "xc3sprog": - return XC3SProg("jtaghs1_fast", "bscan_spi_kc705.bit") - elif self.programmer == "vivado": - return VivadoProgrammer() - elif self.programmer == "impact": - return iMPACT() - else: - raise ValueError("{} programmer is not supported".format(programmer)) - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - try: - self.add_period_constraint(self.lookup_request("clk200").p, 5.0) - except ConstraintError: - pass - try: - self.add_period_constraint(self.lookup_request("eth_clocks").rx, 8.0) - except ConstraintError: - pass - if isinstance(self.toolchain, XilinxISEToolchain): - self.add_platform_command("CONFIG DCI_CASCADE = \"33 32 34\";") - else: - self.add_platform_command("set_property DCI_CASCADE {{32 34}} [get_iobanks 33]") diff --git a/litex/gen/migen/build/platforms/lx9_microboard.py b/litex/gen/migen/build/platforms/lx9_microboard.py deleted file mode 100644 index fb13b1cb..00000000 --- a/litex/gen/migen/build/platforms/lx9_microboard.py +++ /dev/null @@ -1,131 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("user_btn", 0, Pins("V4"), IOStandard("LVCMOS33"), - Misc("PULLDOWN"), Misc("TIG")), - - ("user_led", 0, Pins("P4"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - ("user_led", 1, Pins("L6"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - ("user_led", 2, Pins("F5"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - ("user_led", 3, Pins("C2"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - - ("user_dip", 0, Pins("B3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - ("user_dip", 1, Pins("A3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - ("user_dip", 2, Pins("B4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - ("user_dip", 3, Pins("A4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - - # TI CDCE913 programmable triple-output PLL - ("clk_y1", 0, Pins("V10"), IOStandard("LVCMOS33")), # default: 40 MHz - ("clk_y2", 0, Pins("K15"), IOStandard("LVCMOS33")), # default: 66 2/3 MHz - ("clk_y3", 0, Pins("C10"), IOStandard("LVCMOS33")), # default: 100 MHz - - # Maxim DS1088LU oscillator, not populated - ("clk_backup", 0, Pins("R8"), IOStandard("LVCMOS33")), - - # TI CDCE913 PLL I2C control - ("pll", 0, - Subsignal("scl", Pins("P12")), - Subsignal("sda", Pins("U13")), - Misc("PULLUP"), - IOStandard("LVCMOS33")), - - # Micron N25Q128 SPI Flash - ("spiflash", 0, - Subsignal("clk", Pins("R15")), - Subsignal("cs_n", Pins("V3")), - Subsignal("dq", Pins("T13 R13 T14 V14")), - IOStandard("LVCMOS33")), - - # PMOD extension connectors - ("pmod", 0, - Subsignal("d", Pins("F15 F16 C17 C18 F14 G14 D17 D18")), - IOStandard("LVCMOS33")), - ("pmod", 1, - Subsignal("d", Pins("H12 G13 E16 E18 K12 K13 F17 F18")), - IOStandard("LVCMOS33")), - - ("pmod_diff", 0, - Subsignal("io", Pins("F15 C17 F14 D17 H12 E16 K12 F17")), - Subsignal("iob", Pins("F16 C18 G14 D18 G13 E18 K13 F18")), - IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("T7"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("R7"), Misc("PULLUP")), - IOStandard("LVCMOS33")), - - ("ddram_clock", 0, - Subsignal("p", Pins("G3")), - Subsignal("n", Pins("G1")), - IOStandard("MOBILE_DDR")), # actually DIFF_ - - # Micron MT46H32M16LFBF-5 LPDDR - ("ddram", 0, - Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 " - "D2 D1 F4 D3 G6")), - Subsignal("ba", Pins("F2 F1")), - Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 " - "M3 M1 N2 N1 T2 T1 U2 U1")), - Subsignal("cke", Pins("H7")), - Subsignal("we_n", Pins("E3")), - Subsignal("cs_n", Pins("K6")), # NC! - Subsignal("cas_n", Pins("K5")), - Subsignal("ras_n", Pins("L5")), - Subsignal("dm", Pins("K3", "K4")), - Subsignal("dqs", Pins("L4", "P2")), - Subsignal("rzq", Pins("N4")), - IOStandard("MOBILE_DDR")), - - # Nat Semi DP83848J 10/100 Ethernet PHY - # pull-ups on col and rx_data set phy addr to 11111b - # and prevent isolate mode (addr 00000b) - ("eth_clocks", 0, - Subsignal("rx", Pins("L15")), - Subsignal("tx", Pins("H17")), - IOStandard("LVCMOS33")), - - ("eth", 0, - Subsignal("col", Pins("M18"), Misc("PULLUP")), - Subsignal("crs", Pins("N17"), Misc("PULLDOWN")), - Subsignal("mdc", Pins("M16"), Misc("PULLDOWN")), - Subsignal("mdio", Pins("L18"), Misc("PULLUP")), # 1k5 ext PULLUP - Subsignal("rst_n", Pins("T18"), Misc("TIG")), - Subsignal("rx_data", Pins("T17 N16 N15 P18"), Misc("PULLUP")), - Subsignal("dv", Pins("P17"), Misc("PULLDOWN")), # MII - Subsignal("rx_er", Pins("N18"), Misc("PULLUP")), # auto MDIX - Subsignal("tx_data", Pins("K18 K17 J18 J16")), - Subsignal("tx_en", Pins("L17")), - Subsignal("tx_er", Pins("L16")), # NC! - IOStandard("LVCMOS33")), - ] - - -class Platform(XilinxPlatform): - default_clk_name = "clk_y3" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-2csg324", _io) - self.add_platform_command(""" -CONFIG VCCAUX = "3.3"; -""") - self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g SPI_buswidth:4" - self.toolchain.ise_commands = """ -promgen -w -spi -c FF -p mcs -o {build_name}.mcs -u 0 {build_name}.bit -""" - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - eth_clocks = self.lookup_request("eth_clocks") - self.add_period_constraint(eth_clocks.rx, 40) - self.add_period_constraint(eth_clocks.tx, 40) - self.add_platform_command(""" -TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns; -TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns; -""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) - except ConstraintError: - pass diff --git a/litex/gen/migen/build/platforms/m1.py b/litex/gen/migen/build/platforms/m1.py deleted file mode 100644 index 65216c88..00000000 --- a/litex/gen/migen/build/platforms/m1.py +++ /dev/null @@ -1,152 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import UrJTAG - - -_io = [ - ("user_led", 0, Pins("B16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - ("user_led", 1, Pins("A16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - - ("user_btn", 0, Pins("AB4"), IOStandard("LVCMOS33")), - ("user_btn", 1, Pins("AA4"), IOStandard("LVCMOS33")), - ("user_btn", 2, Pins("AB5"), IOStandard("LVCMOS33")), - - ("clk50", 0, Pins("AB11"), IOStandard("LVCMOS33")), - - # When executing softcore code in-place from the flash, we want - # the flash reset to be released before the system reset. - ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)), - ("norflash", 0, - Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22", - "F21 K17 J17 E22 E20 H18 H19 F20", - "G19 C22 C20 D22 D21 F19 F18 D20 D19")), - Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7", - "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")), - Subsignal("oe_n", Pins("M22")), - Subsignal("we_n", Pins("N20")), - Subsignal("ce_n", Pins("M21")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8) - ), - - ("serial", 0, - Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")) - ), - - ("ddram_clock", 0, - Subsignal("p", Pins("M3")), - Subsignal("n", Pins("L4")), - IOStandard("SSTL2_I") - ), - ("ddram", 0, - Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")), - Subsignal("ba", Pins("A2 E6")), - Subsignal("cs_n", Pins("F7")), - Subsignal("cke", Pins("G7")), - Subsignal("ras_n", Pins("E5")), - Subsignal("cas_n", Pins("C4")), - Subsignal("we_n", Pins("D3")), - Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3", - "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4", - "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")), - Subsignal("dm", Pins("E1 E3 F3 G4")), - Subsignal("dqs", Pins("F1 F2 H5 H6")), - IOStandard("SSTL2_I") - ), - - ("eth_clocks", 0, - Subsignal("phy", Pins("M20")), - Subsignal("rx", Pins("H22")), - Subsignal("tx", Pins("H21")), - IOStandard("LVCMOS33") - ), - ("eth", 0, - Subsignal("rst_n", Pins("R22")), - Subsignal("dv", Pins("V21")), - Subsignal("rx_er", Pins("V22")), - Subsignal("rx_data", Pins("U22 U20 T22 T21")), - Subsignal("tx_en", Pins("N19")), - Subsignal("tx_er", Pins("M19")), - Subsignal("tx_data", Pins("M16 L15 P19 P20")), - Subsignal("col", Pins("W20")), - Subsignal("crs", Pins("W22")), - IOStandard("LVCMOS33") - ), - - ("vga_out", 0, - Subsignal("clk", Pins("A11")), - Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")), - Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")), - Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")), - Subsignal("hsync_n", Pins("A14")), - Subsignal("vsync_n", Pins("C15")), - Subsignal("psave_n", Pins("B14")), - IOStandard("LVCMOS33") - ), - - ("mmc", 0, - Subsignal("clk", Pins("A10")), - Subsignal("cmd", Pins("B18")), - Subsignal("dat", Pins("A18 E16 C17 A17")), - IOStandard("LVCMOS33") - ), - - # Digital video mixer extension board - ("dvi_in", 0, - Subsignal("clk", Pins("A20")), - Subsignal("data0_n", Pins("A21")), - Subsignal("data1", Pins("B21")), - Subsignal("data2_n", Pins("B22")), - Subsignal("scl", Pins("G16")), - Subsignal("sda", Pins("G17")), - IOStandard("LVCMOS33") - ), - ("dvi_in", 1, - Subsignal("clk", Pins("H17")), - Subsignal("data0_n", Pins("H16")), - Subsignal("data1", Pins("F17")), - Subsignal("data2_n", Pins("F16")), - Subsignal("scl", Pins("J16")), - Subsignal("sda", Pins("K16")), - IOStandard("LVCMOS33") - ), - ("dvi_pots", 0, - Subsignal("charge", Pins("A18")), # SD_DAT0 - Subsignal("blackout", Pins("C17")), # SD_DAT2 - Subsignal("crossfade", Pins("A17")), # SD_DAT3 - IOStandard("LVCMOS33") - ) -] - - -class Platform(XilinxPlatform): - identifier = 0x4D31 - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io) - - def create_programmer(self): - return UrJTAG(cable="milkymist", flash_proxy_basename="fjmem-m1.bit") - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - eth_clocks = self.lookup_request("eth_clocks") - self.add_period_constraint(eth_clocks.rx, 40) - self.add_period_constraint(eth_clocks.tx, 40) - self.add_platform_command(""" -TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns; -TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns; -""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) - except ConstraintError: - pass - - for i in range(2): - si = "dviclk"+str(i) - try: - self.add_period_constraint(self.lookup_request("dvi_in", i).clk, 26.7) - except ConstraintError: - pass diff --git a/litex/gen/migen/build/platforms/mercury.py b/litex/gen/migen/build/platforms/mercury.py deleted file mode 100644 index 699218df..00000000 --- a/litex/gen/migen/build/platforms/mercury.py +++ /dev/null @@ -1,138 +0,0 @@ -# This file is Copyright (c) 2015 William D. Jones -# License: BSD - -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg - - -_io = [ - ("clk50", 0, Pins("P43"), IOStandard("LVCMOS33")), - - ("user_btn", 0, Pins("P41"), IOStandard("LVTTL")), - - # The serial interface and flash memory have a shared SPI bus. - # FPGA is secondary - ("spiserial", 0, - Subsignal("cs_n", Pins("P39"), IOStandard("LVTTL")), - Subsignal("clk", Pins("P53"), IOStandard("LVTTL")), - Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")), - Subsignal("miso", Pins("P51"), IOStandard("LVTTL")) - ), - - # FPGA is primary - ("spiflash", 0, - Subsignal("cs_n", Pins("P27"), IOStandard("LVTTL")), - Subsignal("clk", Pins("P53"), IOStandard("LVTTL")), - Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")), - Subsignal("miso", Pins("P51"), IOStandard("LVTTL")) - ), - - ("spiflash2x", 0, - Subsignal("cs_n", Pins("P27")), - Subsignal("clk", Pins("P53")), - Subsignal("dq", Pins("P46", "P51")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - # ADC over SPI- FPGA is primary - ("adc", 0, - Subsignal("cs_n", Pins("P12"), IOStandard("LVTTL")), - Subsignal("clk", Pins("P9"), IOStandard("LVTTL")), - Subsignal("mosi", Pins("P10"), IOStandard("LVTTL")), - Subsignal("miso", Pins("P21"), IOStandard("LVTTL")) - ), - - # GPIO control- SRAM and connectors are shared: these pins control how - # to access each. Recommended to combine with gpio_sram_bus extension, - # since these pins are related but not exposed on connectors. - ("gpio_ctl", 0, - Subsignal("ce_n", Pins("P3")), # Memory chip-enable. Called MEM_CEN - # in schematic. - Subsignal("bussw_oe_n", Pins("P30")), # 5V tolerant GPIO is shared - # w/ memory using this pin. - IOStandard("LVTTL"), Misc("SLEW=FAST") - ) -] - -# Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO -# bus with data, peripheral-select, and control signals? -_connectors = [ - ("GPIO", """P59 P60 P61 P62 P64 P57 - P56 P52 P50 P49 P85 P84 - P83 P78 P77 P65 P70 P71 - P72 P73 P5 P4 P6 P98 - P94 P93 P90 P89 P88 P86"""), # 5V I/O- LVTTL - ("DIO", "P20 P32 P33 P34 P35 P36 P37"), # Fast 3.3V IO (Directly attached - # to FPGA)- LVCMOS33 - ("CLKIO", "P40 P44"), # Clock IO (Can be used as GPIO)- LVCMOS33 - ("INPUT", "P68 P97 P7 P82"), # Input-only pins- LVCMOS33 - ("LED", "P13 P15 P16 P19") # LEDs can be used as pins as well- LVTTL. -] - -# Some default useful extensions- use platform.add_extension() to use, e.g. -# from migen.build.platforms import mercury -# plat = mercury.Platform() -# plat.add_extension(mercury.gpio_sram) - -# SRAM and 5V-tolerant I/O share a parallel bus on 200k gate version. The SRAM -# controller needs to take care of switching the bus between the two. Meant to -# be Cat() into one GPIO bus, and combined with gpio_ctl. -gpio_sram = [ - ("gpio_sram_bus", 0, - Subsignal("a", Pins("""GPIO:0 GPIO:1 GPIO:2 GPIO:3 - GPIO:4 GPIO:5 GPIO:6 GPIO:7 - GPIO:8 GPIO:9 GPIO:10 GPIO:11 - GPIO:12 GPIO:13 GPIO:14 GPIO:15 - GPIO:16 GPIO:17 GPIO:18 GPIO:19""")), - # A19 is actually unused- free for GPIO - # 8-bit data bus - Subsignal("d", Pins("""GPIO:20 GPIO:21 GPIO:22 GPIO:23 - GPIO:24 GPIO:25 GPIO:26 GPIO:27""")), - Subsignal("we_n", Pins("GPIO:28")), - Subsignal("unused", Pins("GPIO:29")), # Only used by GPIO. - # Subsignal("oe_n", Pins()), # If OE wasn't tied to ground on Mercury, - # this pin would be here. - IOStandard("LVTTL"), Misc("SLEW=FAST") - ) -] - -# The "serial port" is in fact over SPI. The creators of the board provide a -# VHDL file for talking over this interface. In light of space constraints and -# the fact that both the FT245RL and FPGA can BOTH be SPI primaries, however, -# it may be necessary to sacrifice two "high-speed" (DIO, INPUT) pins instead. -serial = [ - ("serial", 0, - Subsignal("tx", Pins("DIO:0"), IOStandard("LVCMOS33")), # FTDI D1 - Subsignal("rx", Pins("INPUT:0"), IOStandard("LVCMOS33")) - ) # FTDI D0 -] - -leds = [ - ("user_led", 0, Pins("LED:0"), IOStandard("LVTTL")), - ("user_led", 1, Pins("LED:1"), IOStandard("LVTTL")), - ("user_led", 2, Pins("LED:2"), IOStandard("LVTTL")), - ("user_led", 3, Pins("LED:3"), IOStandard("LVTTL")) -] - -# See: http://www.micro-nova.com/mercury-baseboard/ -# Not implemented yet. -baseboard = [ -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self, device="xc3s200a-4-vq100"): - XilinxPlatform.__init__(self, device, _io, _connectors) - # Small device- optimize for AREA instead of SPEED (LM32 runs at about - # 60-65MHz in AREA configuration). - self.toolchain.xst_opt = """-ifmt MIXED --use_new_parser yes --opt_mode AREA --register_balancing yes""" - - def create_programmer(self): - raise NotImplementedError diff --git a/litex/gen/migen/build/platforms/mimasv2.py b/litex/gen/migen/build/platforms/mimasv2.py deleted file mode 100644 index 703fdc49..00000000 --- a/litex/gen/migen/build/platforms/mimasv2.py +++ /dev/null @@ -1,124 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("clk100", 0, Pins("V10"), IOStandard("LVCMOS33")), - ("clk12", 0, Pins("D9"), IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("A8"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("rx", Pins("B8"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))), - - ("spiflash", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("mosi", Pins("T13")), - Subsignal("miso", Pins("R13"), Misc("PULLUP")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST")), - - ("ddram_clock", 0, - Subsignal("p", Pins("G3")), - Subsignal("n", Pins("G1")), - IOStandard("MOBILE_DDR")), - - ("ddram", 0, - Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")), - Subsignal("ba", Pins("F2 F1")), - Subsignal("cke", Pins("H7")), - Subsignal("ras_n", Pins("L5")), - Subsignal("cas_n", Pins("K5")), - Subsignal("we_n", Pins("E3")), - Subsignal( - "dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1") - ), - Subsignal("dqs", Pins("L4 P2")), - Subsignal("dm", Pins("K3 K4")), - IOStandard("MOBILE_DDR")), - - ("dipswitch", 0, Pins("C17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 1, Pins("C18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 2, Pins("D17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 3, Pins("D18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 4, Pins("E18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 5, Pins("E16"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 6, Pins("F18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 7, Pins("F17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - - ("buttonswitch", 0, Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 1, Pins("K17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 2, Pins("L17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 3, Pins("M16"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 4, Pins("L18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 5, Pins("M18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - - ("user_led", 0, Pins("T18"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 1, Pins("T17"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 3, Pins("U17"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 4, Pins("N16"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 5, Pins("N15"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 6, Pins("P16"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 7, Pins("P15"), IOStandard("LVCMOS33"), Drive(8)), - - ("mmc", 0, - Subsignal("dat", Pins("K14 G18 J13 L13"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - - Subsignal("cmd", Pins("G16"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - - Subsignal("clk", Pins("L12"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))), - - ("sevenseg", 0, - Subsignal("segment7", Pins("A3"), IOStandard("LVCMOS33")), # A - Subsignal("segment6", Pins("B4"), IOStandard("LVCMOS33")), # B - Subsignal("segment5", Pins("A4"), IOStandard("LVCMOS33")), # C - Subsignal("segment4", Pins("C4"), IOStandard("LVCMOS33")), # D - Subsignal("segment3", Pins("C5"), IOStandard("LVCMOS33")), # E - Subsignal("segment2", Pins("D6"), IOStandard("LVCMOS33")), # F - Subsignal("segment1", Pins("C6"), IOStandard("LVCMOS33")), # G - Subsignal("segment0", Pins("A5"), IOStandard("LVCMOS33")), # Dot - Subsignal("enable0", Pins("B2"), IOStandard("LVCMOS33")), # EN0 - Subsignal("enable1", Pins("A2"), IOStandard("LVCMOS33")), # EN1 - Subsignal("enable2", Pins("B3"), IOStandard("LVCMOS33"))), # EN2 - - - ("audio", 0, - Subsignal("channel1", Pins("B16"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("channel2", Pins("A16"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))), - - ("vga_out", 0, - Subsignal("hsync_n", Pins("B12"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("vsync_n", Pins("A12"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("r", Pins("A9 B9 C9"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("g", Pins("C10 A10 C11"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("b", Pins("B11 A11"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))) -] - -_connectors = [ - ("P6", "T3 R3 V5 U5 V4 T4 V7 U7"), - ("P7", "V11 U11 V13 U13 T10 R10 T11 R11"), - ("P8", "L16 L15 K16 K15 J18 J16 H18 H17") -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-csg324-2", _io, _connectors) - - def create_programmer(self): - raise NotImplementedError diff --git a/litex/gen/migen/build/platforms/minispartan6.py b/litex/gen/migen/build/platforms/minispartan6.py deleted file mode 100644 index c46fa29c..00000000 --- a/litex/gen/migen/build/platforms/minispartan6.py +++ /dev/null @@ -1,126 +0,0 @@ -# This file is Copyright (c) 2015 Matt O'Gorman -# License: BSD - -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg, FpgaProg - - -_io = [ - ("user_led", 0, Pins("P11"), IOStandard("LVCMOS33")), - ("user_led", 1, Pins("N9"), IOStandard("LVCMOS33")), - ("user_led", 2, Pins("M9"), IOStandard("LVCMOS33")), - ("user_led", 3, Pins("P9"), IOStandard("LVCMOS33")), - ("user_led", 4, Pins("T8"), IOStandard("LVCMOS33")), - ("user_led", 5, Pins("N8"), IOStandard("LVCMOS33")), - ("user_led", 6, Pins("P8"), IOStandard("LVCMOS33")), - ("user_led", 7, Pins("P7"), IOStandard("LVCMOS33")), - - ("user_sw", 0, Pins("L1"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("user_sw", 1, Pins("L3"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("user_sw", 2, Pins("L4"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("user_sw", 3, Pins("L5"), IOStandard("LVCMOS33"), Misc("PULLUP")), - - ("clk32", 0, Pins("J4"), IOStandard("LVCMOS33")), - ("clk50", 0, Pins("K3"), IOStandard("LVCMOS33")), - - ("spiflash", 0, - Subsignal("cs_n", Pins("T3"), IOStandard("LVCMOS33")), - Subsignal("clk", Pins("R11"), IOStandard("LVCMOS33")), - Subsignal("mosi", Pins("T10"), IOStandard("LVCMOS33")), - Subsignal("miso", Pins("P10"), IOStandard("LVCMOS33")) - ), - - ("adc", 0, - Subsignal("cs_n", Pins("F6"), IOStandard("LVCMOS33")), - Subsignal("clk", Pins("G6"), IOStandard("LVCMOS33")), - Subsignal("mosi", Pins("H4"), IOStandard("LVCMOS33")), - Subsignal("miso", Pins("H5"), IOStandard("LVCMOS33")) - ), - - ("serial", 0, - Subsignal("tx", Pins("N6"), IOStandard("LVCMOS33")), # FTDI D1 - Subsignal("rx", Pins("M7"), IOStandard("LVCMOS33")) # FTDI D0 - ), - - ("audio", 0, - Subsignal("a0", Pins("B8"), IOStandard("LVCMOS33")), - Subsignal("a1", Pins("A8"), IOStandard("LVCMOS33")) - ), - - ("sdram_clock", 0, Pins("G16"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), - ("sdram", 0, - Subsignal("a", Pins("T15 R16 P15 P16 N16 M15 M16 L16 K15 K16 R15 J16 H15")), - Subsignal("dq", Pins("T13 T12 R12 T9 R9 T7 R7 T6 F16 E15 E16 D16 B16 B15 C16 C15")), - Subsignal("we_n", Pins("R5")), - Subsignal("ras_n", Pins("R2")), - Subsignal("cas_n", Pins("T4")), - Subsignal("cs_n", Pins("R1")), - Subsignal("cke", Pins("H16")), - Subsignal("ba", Pins("R14 T14")), - Subsignal("dm", Pins("T5 F15")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), - - ("usb_fifo", 0, - Subsignal("data", Pins("M7 N6 M6 P5 N5 P4 P2 P1")), - Subsignal("rxf_n", Pins("N3")), - Subsignal("txe_n", Pins("N1")), - Subsignal("rd_n", Pins("M1")), - Subsignal("wr_n", Pins("M2")), - Subsignal("siwua", Pins("M3")), - IOStandard("LVCMOS33"), Drive(8), Misc("SLEW=FAST") - ), - - ("sd", 0, - Subsignal("sck", Pins("L12")), - Subsignal("d3", Pins("K12")), - Subsignal("d", Pins("M10")), - Subsignal("d1", Pins("L10")), - Subsignal("d2", Pins("J11")), - Subsignal("cmd", Pins("K11")), - IOStandard("LVCMOS33") - ), - - ("dvi_in", 0, - Subsignal("clk_p", Pins("C9"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("A9"), IOStandard("TMDS_33")), - Subsignal("data_p", Pins("C7 B6 B5"), IOStandard("TMDS_33")), - Subsignal("data_n", Pins("A7 A6 A5"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("C1"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("B1"), IOStandard("LVCMOS33")) - ), - - ("dvi_out", 0, - Subsignal("clk_p", Pins("B14"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("A14"), IOStandard("TMDS_33")), - Subsignal("data_p", Pins("C13 B12 C11"), IOStandard("TMDS_33")), - Subsignal("data_n", Pins("A13 A12 A11"), IOStandard("TMDS_33")), - ) -] - -_connectors = [ - ("A", "E7 C8 D8 E8 D9 A10 B10 C10 E10 F9 F10 D11"), - ("B", "E11 D14 D12 E12 E13 F13 F12 F14 G12 H14 J14"), - ("C", "J13 J12 K14 L14 L13 M14 M13 N14 M12 N12 P12 M11"), - ("D", "D6 C6 E6 C5"), - ("E", "D5 A4 G5 A3 B3 A2 B2 C3 C2 D3 D1 E3"), - ("F", "E2 E1 E4 F4 F5 G3 F3 G1 H3 H1 H2 J1") -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk32" - default_clk_period = 31.25 - - def __init__(self, device="xc6slx9", programmer="xc3sprog"): - self.programmer = programmer - XilinxPlatform.__init__(self, device+"-3-ftg256", _io, _connectors) - - def create_programmer(self): - if self.programmer == "xc3sprog": - return XC3SProg("minispartan6", "bscan_spi_minispartan6.bit") - elif self.programmer == "fpgaprog": - return FpgaProg() - else: - raise ValueError("{} programmer is not supported".format(programmer)) diff --git a/litex/gen/migen/build/platforms/mixxeo.py b/litex/gen/migen/build/platforms/mixxeo.py deleted file mode 100644 index 8d4c85d8..00000000 --- a/litex/gen/migen/build/platforms/mixxeo.py +++ /dev/null @@ -1,188 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import UrJTAG - - -_io = [ - ("user_led", 0, Pins("V5"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - - ("clk50", 0, Pins("AB13"), IOStandard("LVCMOS33")), - - # When executing softcore code in-place from the flash, we want - # the flash reset to be released before the system reset. - ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)), - ("norflash", 0, - Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22", - "F21 K17 J17 E22 E20 H18 H19 F20", - "G19 C22 C20 D22 D21 F19 F18 D20 D19")), - Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7", - "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")), - Subsignal("oe_n", Pins("M22")), - Subsignal("we_n", Pins("N20")), - Subsignal("ce_n", Pins("M21")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8) - ), - - ("serial", 0, - Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")) - ), - - ("ddram_clock", 0, - Subsignal("p", Pins("M3")), - Subsignal("n", Pins("L4")), - IOStandard("SSTL2_I") - ), - ("ddram", 0, - Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")), - Subsignal("ba", Pins("A2 E6")), - Subsignal("cs_n", Pins("F7")), - Subsignal("cke", Pins("G7")), - Subsignal("ras_n", Pins("E5")), - Subsignal("cas_n", Pins("C4")), - Subsignal("we_n", Pins("D3")), - Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3", - "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4", - "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")), - Subsignal("dm", Pins("E1 E3 F3 G4")), - Subsignal("dqs", Pins("F1 F2 H5 H6")), - IOStandard("SSTL2_I") - ), - - ("eth_clocks", 0, - Subsignal("phy", Pins("M20")), - Subsignal("rx", Pins("H22")), - Subsignal("tx", Pins("H21")), - IOStandard("LVCMOS33") - ), - ("eth", 0, - Subsignal("rst_n", Pins("R22")), - Subsignal("dv", Pins("V21")), - Subsignal("rx_er", Pins("V22")), - Subsignal("rx_data", Pins("U22 U20 T22 T21")), - Subsignal("tx_en", Pins("N19")), - Subsignal("tx_er", Pins("M19")), - Subsignal("tx_data", Pins("M16 L15 P19 P20")), - Subsignal("col", Pins("W20")), - Subsignal("crs", Pins("W22")), - IOStandard("LVCMOS33") - ), - - ("vga_out", 0, - Subsignal("clk", Pins("A10")), - Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")), - Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")), - Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")), - Subsignal("hsync_n", Pins("A14")), - Subsignal("vsync_n", Pins("C15")), - Subsignal("psave_n", Pins("B14")), - IOStandard("LVCMOS33") - ), - ("dvi_out", 0, - Subsignal("clk_p", Pins("W12"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("Y12"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("Y16"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("W15"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("AA16"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("AB16"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("Y15"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("AB15"), IOStandard("TMDS_33")), - ), - - ("mmc", 0, - Subsignal("clk", Pins("J3")), - Subsignal("cmd", Pins("K1")), - Subsignal("dat", Pins("J6 K6 N1 K5")), - IOStandard("LVCMOS33") - ), - - ("dvi_in", 0, - Subsignal("clk_p", Pins("K20"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("K19"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("B21"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("B22"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("A20"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("A21"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("K16"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("J16"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("G20"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("H16"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("G22"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("G17"), IOStandard("LVCMOS33")) - ), - ("dvi_in", 1, - Subsignal("clk_p", Pins("C11"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("A11"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("B18"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("A18"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("C17"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("A17"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("E16"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("D17"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("F17"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("F16"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("G16"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("B20"), IOStandard("LVCMOS33")) - ), - ("dvi_in", 2, - Subsignal("clk_p", Pins("Y11"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("AB11"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("V11"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("W11"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("AA10"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("AB10"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("R11"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("T11"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("C16"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("B16"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("D6"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("A4"), IOStandard("LVCMOS33")) - ), - ("dvi_in", 3, - Subsignal("clk_p", Pins("J20"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("J22"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("P18"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("R19"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("P17"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("N16"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("M17"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("M18"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("P21"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("N22"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("H17"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("C19"), IOStandard("LVCMOS33")) - ), -] - - -class Platform(XilinxPlatform): - identifier = 0x4D58 - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io) - self.add_platform_command("CONFIG VCCAUX=\"3.3\";\n") - - def create_programmer(self): - return UrJTAG("fjmem-mixxeo.bit") - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - eth_clocks = self.lookup_request("eth_clocks") - self.add_period_constraint(eth_clocks.rx, 40) - self.add_period_constraint(eth_clocks.tx, 40) - self.add_platform_command(""" -TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns; -TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns; -""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) - except ConstraintError: - pass - - for i in range(4): - try: - self.add_period_constraint(self.lookup_request("dvi_in", i).clk_p, 12) - except ConstraintError: - pass diff --git a/litex/gen/migen/build/platforms/ml605.py b/litex/gen/migen/build/platforms/ml605.py deleted file mode 100644 index 04184b74..00000000 --- a/litex/gen/migen/build/platforms/ml605.py +++ /dev/null @@ -1,60 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - # System clock (Differential 200MHz) - ("clk200", 0, - Subsignal("p", Pins("J9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("n", Pins("H9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")) - ), - - # User clock (66MHz) - ("clk66", 0, Pins("U23"), IOStandard("LVCMOS25")), - - # CPU reset switch - ("cpu_reset", 0, Pins("H10"), IOStandard("SSTL15")), - - # LEDs - ("user_led", 0, Pins("AC22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 1, Pins("AC24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 2, Pins("AE22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 3, Pins("AE23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 4, Pins("AB23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 5, Pins("AG23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 6, Pins("AE24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 7, Pins("AD24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - - # USB-to-UART - ("serial", 0, - Subsignal("tx", Pins("J25"), IOStandard("LVCMOS25")), - Subsignal("rx", Pins("J24"), IOStandard("LVCMOS25")) - ), - - # 10/100/1000 Tri-Speed Ethernet PHY - ("eth_clocks", 0, - Subsignal("rx", Pins("AP11")), - Subsignal("tx", Pins("AD12")), - IOStandard("LVCMOS25") - ), - ("eth", 0, - Subsignal("rst_n", Pins("AH13")), - Subsignal("dv", Pins("AM13")), - Subsignal("rx_er", Pins("AG12")), - Subsignal("rx_data", Pins("AN13 AF14 AE14 AN12 AM12 AD11 AC12 AC13")), - Subsignal("tx_en", Pins("AJ10")), - Subsignal("tx_er", Pins("AH10")), - Subsignal("tx_data", Pins("AM11 AL11 AG10 AG11 AL10 AM10 AE11 AF11")), - Subsignal("col", Pins("AK13")), - Subsignal("crs", Pins("AL13")), - IOStandard("LVCMOS25") - ) -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk200" - default_clk_period = 5 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6vlx240t-ff1156-1", _io) diff --git a/litex/gen/migen/build/platforms/papilio_pro.py b/litex/gen/migen/build/platforms/papilio_pro.py deleted file mode 100644 index 8ee33005..00000000 --- a/litex/gen/migen/build/platforms/papilio_pro.py +++ /dev/null @@ -1,62 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg - - -_io = [ - ("user_led", 0, Pins("P112"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - - ("clk32", 0, Pins("P94"), IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("P105"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("P101"), IOStandard("LVCMOS33"), Misc("PULLUP")) - ), - - ("spiflash", 0, - Subsignal("cs_n", Pins("P38")), - Subsignal("clk", Pins("P70")), - Subsignal("mosi", Pins("P64")), - Subsignal("miso", Pins("P65"), Misc("PULLUP")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), - ("spiflash2x", 0, - Subsignal("cs_n", Pins("P38")), - Subsignal("clk", Pins("P70")), - Subsignal("dq", Pins("P64", "P65")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), - - ("sdram_clock", 0, Pins("P32"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), - ("sdram", 0, - Subsignal("a", Pins("P140 P139 P138 P137 P46 P45 P44", - "P43 P41 P40 P141 P35 P34")), - Subsignal("ba", Pins("P143 P142")), - Subsignal("cs_n", Pins("P1")), - Subsignal("cke", Pins("P33")), - Subsignal("ras_n", Pins("P2")), - Subsignal("cas_n", Pins("P5")), - Subsignal("we_n", Pins("P6")), - Subsignal("dq", Pins("P9 P10 P11 P12 P14 P15 P16 P8 P21 P22 P23 P24 P26 P27 P29 P30")), - Subsignal("dm", Pins("P7 P17")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ) -] - -_connectors = [ - ("A", "P48 P51 P56 P58 P61 P66 P67 P75 P79 P81 P83 P85 P88 P93 P98 P100"), - ("B", "P99 P97 P92 P87 P84 P82 P80 P78 P74 P95 P62 P59 P57 P55 P50 P47"), - ("C", "P114 P115 P116 P117 P118 P119 P120 P121 P123 P124 P126 P127 P131 P132 P133 P134") -] - - -class Platform(XilinxPlatform): - identifier = 0x5050 - default_clk_name = "clk32" - default_clk_period = 31.25 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-tqg144-2", _io, _connectors) - - def create_programmer(self): - return XC3SProg("papilio", "bscan_spi_lx9_papilio.bit") diff --git a/litex/gen/migen/build/platforms/pipistrello.py b/litex/gen/migen/build/platforms/pipistrello.py deleted file mode 100644 index c202556a..00000000 --- a/litex/gen/migen/build/platforms/pipistrello.py +++ /dev/null @@ -1,138 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg - - -_io = [ - ("user_led", 0, Pins("V16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at hdmi - ("user_led", 1, Pins("U16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at hdmi - ("user_led", 2, Pins("A16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at msd - ("user_led", 3, Pins("A15"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at msd - ("user_led", 4, Pins("A12"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at usb - - ("user_btn", 0, Pins("N14"), IOStandard("LVTTL"), Misc("PULLDOWN")), - - ("clk50", 0, Pins("H17"), IOStandard("LVTTL")), - - ("serial", 0, - Subsignal("tx", Pins("A10")), - Subsignal("rx", Pins("A11"), Misc("PULLUP")), - Subsignal("cts", Pins("C10"), Misc("PULLUP")), - Subsignal("rts", Pins("A9"), Misc("PULLUP")), - IOStandard("LVTTL"), - ), - - ("usb_fifo", 0, - Subsignal("data", Pins("A11 A10 C10 A9 B9 A8 B8 A7")), - Subsignal("rxf_n", Pins("C7")), - Subsignal("txe_n", Pins("A6")), - Subsignal("rd_n", Pins("B6")), - Subsignal("wr_n", Pins("A5")), - Subsignal("siwua", Pins("C5")), - IOStandard("LVTTL"), - ), - - ("hdmi", 0, - Subsignal("clk_p", Pins("U5"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("V5"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("T6"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("V6"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("U7"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("V7"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("U8"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("V8"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("V9"), IOStandard("I2C")), - Subsignal("sda", Pins("T9"), IOStandard("I2C")), - Subsignal("hpd_notif", Pins("R8"), IOStandard("LVTTL")), - ), - - ("spiflash", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("mosi", Pins("T13")), - Subsignal("miso", Pins("R13"), Misc("PULLUP")), - Subsignal("wp", Pins("T14")), - Subsignal("hold", Pins("V14")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - ("spiflash2x", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("dq", Pins("T13 R13"), Misc("PULLUP")), - Subsignal("wp", Pins("T14")), - Subsignal("hold", Pins("V14")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - ("spiflash4x", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("dq", Pins("T13 R13 T14 V14"), Misc("PULLUP")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - ("mmc", 0, - Subsignal("clk", Pins("A3")), - Subsignal("cmd", Pins("B3"), Misc("PULLUP")), - Subsignal("dat", Pins("B4 A4 B2 A2"), Misc("PULLUP")), - IOStandard("SDIO") - ), - - ("mmc_spi", 0, - Subsignal("cs_n", Pins("A2"), Misc("PULLUP")), - Subsignal("clk", Pins("A3")), - Subsignal("mosi", Pins("B3")), - Subsignal("miso", Pins("B4"), Misc("PULLUP")), - IOStandard("SDIO") - ), - - ("audio", 0, - Subsignal("l", Pins("R7"), Misc("SLEW=SLOW")), - Subsignal("r", Pins("T7"), Misc("SLEW=SLOW")), - IOStandard("LVTTL"), - ), - - ("pmod", 0, - Subsignal("d", Pins("D9 C8 D6 C4 B11 C9 D8 C6")), - IOStandard("LVTTL") - ), - - ("ddram_clock", 0, - Subsignal("p", Pins("G3")), - Subsignal("n", Pins("G1")), - IOStandard("MOBILE_DDR") - ), - - ("ddram", 0, - Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")), - Subsignal("ba", Pins("F2 F1")), - Subsignal("cke", Pins("H7")), - Subsignal("ras_n", Pins("L5")), - Subsignal("cas_n", Pins("K5")), - Subsignal("we_n", Pins("E3")), - Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1")), - Subsignal("dqs", Pins("L4 P2")), - Subsignal("dm", Pins("K3 K4")), - IOStandard("MOBILE_DDR") - ) -] - -_connectors = [ - ("A", "U18 T17 P17 P16 N16 N17 M16 L15 L17 K15 K17 J16 H15 H18 F18 D18"), - ("B", "C18 E18 G18 H16 J18 K18 K16 L18 L16 M18 N18 N15 P15 P18 T18 U17"), - ("C", "F17 F16 E16 G16 F15 G14 F14 H14 H13 J13 G13 H12 K14 K13 K12 L12"), -] - - -class Platform(XilinxPlatform): - identifier = 0x5049 - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx45-csg324-3", _io, _connectors) - self.toolchain.bitgen_opt += " -g Compress -g ConfigRate:6" - - def create_programmer(self): - return XC3SProg("papilio", "bscan_spi_lx45_csg324.bit") diff --git a/litex/gen/migen/build/platforms/rhino.py b/litex/gen/migen/build/platforms/rhino.py deleted file mode 100644 index 0cb99596..00000000 --- a/litex/gen/migen/build/platforms/rhino.py +++ /dev/null @@ -1,142 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("user_led", 0, Pins("Y3")), - ("user_led", 1, Pins("Y1")), - ("user_led", 2, Pins("W2")), - ("user_led", 3, Pins("W1")), - ("user_led", 4, Pins("V3")), - ("user_led", 5, Pins("V1")), - ("user_led", 6, Pins("U2")), - ("user_led", 7, Pins("U1")), - - ("clk100", 0, - Subsignal("p", Pins("B14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("n", Pins("A14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")) - ), - - ("gpio", 0, Pins("R8")), - - ("gpmc", 0, - Subsignal("clk", Pins("R26")), - Subsignal("a", Pins("N17 N18 L23 L24 N19 N20 N21 N22 P17 P19")), - Subsignal("d", Pins("N23 N24 R18 R19 P21 P22 R20 R21 P24 P26 R23 R24 T22 T23 U23 R25")), - Subsignal("we_n", Pins("W26")), - Subsignal("oe_n", Pins("AA25")), - Subsignal("ale_n", Pins("AA26")), - Subsignal("wait", Pins("AD26")), # WAIT1/BUSY0 - IOStandard("LVCMOS33")), - # Warning: CS are numbered 1-7 on ARM side and 0-6 on FPGA side. - # Numbers here are given on the FPGA side. - ("gpmc_ce_n", 0, Pins("V23"), IOStandard("LVCMOS33")), # nCS0 - ("gpmc_ce_n", 1, Pins("U25"), IOStandard("LVCMOS33")), # nCS1 - ("gpmc_ce_n", 2, Pins("W25"), IOStandard("LVCMOS33")), # nCS6 - ("gpmc_dmareq_n", 0, Pins("T24"), IOStandard("LVCMOS33")), # nCS2 - ("gpmc_dmareq_n", 1, Pins("T26"), IOStandard("LVCMOS33")), # nCS3 - ("gpmc_dmareq_n", 2, Pins("V24"), IOStandard("LVCMOS33")), # nCS4 - ("gpmc_dmareq_n", 3, Pins("V26"), IOStandard("LVCMOS33")), # nCS5 - - # FMC150 - ("fmc150_ctrl", 0, - Subsignal("spi_sclk", Pins("AE5")), - Subsignal("spi_data", Pins("AF5")), - - Subsignal("adc_sdo", Pins("U13")), - Subsignal("adc_en_n", Pins("AA15")), - Subsignal("adc_reset", Pins("V13")), - - Subsignal("cdce_sdo", Pins("AA8")), - Subsignal("cdce_en_n", Pins("Y9")), - Subsignal("cdce_reset_n", Pins("AB7")), - Subsignal("cdce_pd_n", Pins("AC6")), - Subsignal("cdce_pll_status", Pins("W7")), - Subsignal("cdce_ref_en", Pins("W8")), - - Subsignal("dac_sdo", Pins("W9")), - Subsignal("dac_en_n", Pins("W10")), - - Subsignal("mon_sdo", Pins("AC5")), - Subsignal("mon_en_n", Pins("AD6")), - Subsignal("mon_reset_n", Pins("AF6")), - Subsignal("mon_int_n", Pins("AD5")), - - Subsignal("pg_c2m", Pins("AA23"), IOStandard("LVCMOS33")) - ), - ("ti_dac", 0, # DAC3283 - Subsignal("dat_p", Pins("AA10 AA9 V11 Y11 W14 Y12 AD14 AE13"), IOStandard("LVDS_25")), - Subsignal("dat_n", Pins("AB11 AB9 V10 AA11 Y13 AA12 AF14 AF13"), IOStandard("LVDS_25")), - Subsignal("frame_p", Pins("AB13"), IOStandard("LVDS_25")), - Subsignal("frame_n", Pins("AA13"), IOStandard("LVDS_25")), - Subsignal("txenable", Pins("AB15"), IOStandard("LVCMOS25")) - ), - ("ti_adc", 0, # ADS62P49 - Subsignal("dat_a_p", Pins("AB14 Y21 W20 AB22 V18 W17 AA21")), - Subsignal("dat_a_n", Pins("AC14 AA22 Y20 AC22 W19 W18 AB21")), - Subsignal("dat_b_p", Pins("Y17 U15 AA19 W16 AA18 Y15 V14")), - Subsignal("dat_b_n", Pins("AA17 V16 AB19 Y16 AB17 AA16 V15")), - IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE") - ), - ("fmc150_clocks", 0, - Subsignal("dac_clk_p", Pins("V12"), IOStandard("LVDS_25")), - Subsignal("dac_clk_n", Pins("W12"), IOStandard("LVDS_25")), - Subsignal("adc_clk_p", Pins("AE15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("adc_clk_n", Pins("AF15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("clk_to_fpga", Pins("W24"), IOStandard("LVCMOS25")) - ), - - ("fmc150_ext_trigger", 0, Pins("U26")), - - # Vermeer radar testbed - # Switch controller - ("pca9555", 0, - Subsignal("sda", Pins("C13")), - Subsignal("scl", Pins("G8")), - IOStandard("LVCMOS33") - ), - # TX path - ("pe43602", 0, - Subsignal("d", Pins("H8")), - Subsignal("clk", Pins("B3")), - Subsignal("le", Pins("F7")), - IOStandard("LVCMOS33") - ), - ("rfmd2081", 0, - Subsignal("enx", Pins("E5")), - Subsignal("sclk", Pins("G6")), - Subsignal("sdata", Pins("F5")), - Subsignal("locked", Pins("E6")), - IOStandard("LVCMOS33") - ), - # RX path - ("lmh6521", 0, - Subsignal("scsb", Pins("C5")), - Subsignal("sclk", Pins("G10")), - Subsignal("sdi", Pins("D5")), - Subsignal("sdo", Pins("F9")), - IOStandard("LVCMOS33") - ), - ("lmh6521", 1, - Subsignal("scsb", Pins("E10")), - Subsignal("sclk", Pins("A4")), - Subsignal("sdi", Pins("B4")), - Subsignal("sdo", Pins("H10")), - IOStandard("LVCMOS33") - ), - ("rffc5071", 0, - Subsignal("enx", Pins("A2")), - Subsignal("sclk", Pins("G9")), - Subsignal("sdata", Pins("H9")), - Subsignal("locked", Pins("A3")), - IOStandard("LVCMOS33") - ) -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx150t-fgg676-3", _io) diff --git a/litex/gen/migen/build/platforms/roach.py b/litex/gen/migen/build/platforms/roach.py deleted file mode 100644 index 19c1ccb4..00000000 --- a/litex/gen/migen/build/platforms/roach.py +++ /dev/null @@ -1,35 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("epb", 0, - Subsignal("cs_n", Pins("K13")), - Subsignal("r_w_n", Pins("AF20")), - Subsignal("be_n", Pins("AF14 AF18")), - Subsignal("oe_n", Pins("AF21")), - Subsignal("addr", Pins("AE23 AE22 AG18 AG12 AG15 AG23 AF19 AE12 AG16 AF13 AG20 AF23", - "AH17 AH15 L20 J22 H22 L15 L16 K22 K21 K16 J15")), - Subsignal("addr_gp", Pins("L21 G22 K23 K14 L14 J12")), - Subsignal("data", Pins("AF15 AE16 AE21 AD20 AF16 AE17 AE19 AD19 AG22 AH22 AH12 AG13", - "AH20 AH19 AH14 AH13")), - Subsignal("rdy", Pins("K12")), - IOStandard("LVCMOS33") - ), - ("roach_clocks", 0, - Subsignal("epb_clk", Pins("AH18"), IOStandard("LVCMOS33")), - Subsignal("sys_clk_n", Pins("H13")), - Subsignal("sys_clk_p", Pins("J14")), - Subsignal("aux0_clk_p", Pins("G15")), - Subsignal("aux0_clk_n", Pins("G16")), - Subsignal("aux1_clk_p", Pins("H14")), - Subsignal("aux1_clk_n", Pins("H15")), - Subsignal("dly_clk_n", Pins("J17")), - Subsignal("dly_clk_p", Pins("J16")), - ), -] - - -class Platform(XilinxPlatform): - def __init__(self): - XilinxPlatform.__init__(self, "xc5vsx95t-ff1136-1", _io) diff --git a/litex/gen/migen/build/platforms/sim.py b/litex/gen/migen/build/platforms/sim.py deleted file mode 100644 index 0e4a40d1..00000000 --- a/litex/gen/migen/build/platforms/sim.py +++ /dev/null @@ -1,45 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.sim import SimPlatform - - -class SimPins(Pins): - def __init__(self, n): - Pins.__init__(self, "s "*n) - -_io = [ - ("sys_clk", 0, SimPins(1)), - ("sys_rst", 0, SimPins(1)), - ("serial", 0, - Subsignal("source_stb", SimPins(1)), - Subsignal("source_ack", SimPins(1)), - Subsignal("source_data", SimPins(8)), - - Subsignal("sink_stb", SimPins(1)), - Subsignal("sink_ack", SimPins(1)), - Subsignal("sink_data", SimPins(8)), - ), - ("eth_clocks", 0, - Subsignal("none", SimPins(1)), - ), - ("eth", 0, - Subsignal("source_stb", SimPins(1)), - Subsignal("source_ack", SimPins(1)), - Subsignal("source_data", SimPins(8)), - - Subsignal("sink_stb", SimPins(1)), - Subsignal("sink_ack", SimPins(1)), - Subsignal("sink_data", SimPins(8)), - ), -] - - -class Platform(SimPlatform): - is_sim = True - default_clk_name = "sys_clk" - default_clk_period = 1000 # on modern computers simulate at ~ 1MHz - - def __init__(self): - SimPlatform.__init__(self, "SIM", _io) - - def do_finalize(self, fragment): - pass diff --git a/litex/gen/migen/build/platforms/usrp_b100.py b/litex/gen/migen/build/platforms/usrp_b100.py deleted file mode 100644 index d2541263..00000000 --- a/litex/gen/migen/build/platforms/usrp_b100.py +++ /dev/null @@ -1,152 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("clk64", 0, - Subsignal("p", Pins("R7")), - Subsignal("n", Pins("T7")), - IOStandard("LVDS_33"), - Misc("DIFF_TERM=TRUE"), - ), - - ("pps", 0, Pins("M14"), Misc("TIG")), - ("reset_n", 0, Pins("D5"), Misc("TIG")), - ("codec_reset", 0, Pins("B14")), - # recycles fpga_cfg_cclk for reset from fw - ("ext_reset", 0, Pins("R14")), - - ("i2c", 0, - Subsignal("sda", Pins("T13")), - Subsignal("scl", Pins("R13")), - ), - - ("cgen", 0, - Subsignal("st_ld", Pins("M13")), - Subsignal("st_refmon", Pins("J14")), - Subsignal("st_status", Pins("P6")), - Subsignal("ref_sel", Pins("T2")), - Subsignal("sync_b", Pins("H15")), - ), - - ("fx2_ifclk", 0, Pins("T8")), - ("fx2_gpif", 0, - Subsignal("d", Pins("P8 P9 N9 T9 R9 P11 P13 N12 " - "T3 R3 P5 N6 T6 T5 N8 P7")), - Subsignal("ctl", Pins("M7 M9 M11 P12")), - Subsignal("slwr", Pins("T4")), # rdy0 - Subsignal("slrd", Pins("R5")), # rdy1 - # Subsignal("rdy2", Pins("T10")), - # Subsignal("rdy3", Pins("N11")), - # Subsignal("cs", Pins("P12")), - Subsignal("sloe", Pins("R11")), - Subsignal("pktend", Pins("P10")), - Subsignal("adr", Pins("T11 H16")), - ), - - ("user_led", 0, Pins("P4"), Misc("TIG")), - ("user_led", 1, Pins("N4"), Misc("TIG")), - ("user_led", 2, Pins("R2"), Misc("TIG")), - - ("debug_clk", 0, Pins("K15 K14")), - ("debug", 0, Pins( - "K16 J16 C16 C15 E13 D14 D16 D15 " - "E14 F13 G13 F14 E16 F15 H13 G14 " - "G16 F16 J12 J13 L14 L16 M15 M16 " - "L13 K13 P16 N16 R15 P15 N13 N14")), - - ("adc", 0, - Subsignal("sync", Pins("D10")), - Subsignal("d", Pins("A4 B3 A3 D9 C10 A9 C9 D8 " - "C8 B8 A8 B15")), - ), - ("dac", 0, - Subsignal("blank", Pins("K1")), - Subsignal("sync", Pins("J2")), - Subsignal("d", Pins("J1 H3 J3 G2 H1 N3 M4 R1 " - "P2 P1 M1 N1 M3 L4")), - ), - ("codec_spi", 0, - Subsignal("sclk", Pins("K3")), - Subsignal("sen", Pins("D13")), - Subsignal("mosi", Pins("C13")), - Subsignal("miso", Pins("G4")), - ), - - ("aux_spi", 0, - Subsignal("sen", Pins("C12")), - Subsignal("sclk", Pins("D12")), - Subsignal("miso", Pins("J5")), - ), - ("rx_io", 0, Pins("D7 C6 A6 B6 E9 A7 C7 B10 " - "A10 C11 A11 D11 B12 A12 A14 A13")), - ("tx_io", 0, Pins("K4 L3 L2 F1 F3 G3 E3 E2 " - "E4 F4 D1 E1 D4 D3 C2 C1")), - ("rx_spi", 0, - Subsignal("miso", Pins("E6")), - Subsignal("sen", Pins("B4")), - Subsignal("mosi", Pins("A5")), - Subsignal("sclk", Pins("C5")), - ), - ("tx_spi", 0, - Subsignal("miso", Pins("J4")), - Subsignal("sen", Pins("N2")), - Subsignal("mosi", Pins("L1")), - Subsignal("sclk", Pins("G1")), - ), - - # these are just for information. do not request. - ("mystery_bus", 0, Pins("C4 E7")), - ("fpga_cfg", - Subsignal("din", Pins("T14")), - Subsignal("cclk", Pins("R14")), - Subsignal("init_b", Pins("T12")), - Subsignal("prog_b", Pins("A2")), - Subsignal("done", Pins("T15")), - ), - ("jtag", - Subsignal("tms", Pins("B2")), - Subsignal("tdo", Pins("B16")), - Subsignal("tdi", Pins("B1")), - Subsignal("tck", Pins("A15")), - ), -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk64" - default_clk_period = 15.625 - - def __init__(self): - XilinxPlatform.__init__(self, "xc3s1400a-ft256-4", _io) - self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g UnusedPin:PullUp" - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - self.add_platform_command(""" -TIMESPEC TS_Pad2Pad = FROM PADS TO PADS 7 ns; -""") - - try: - ifclk = self.lookup_request("fx2_ifclk") - gpif = self.lookup_request("fx2_gpif") - for i, d in [(gpif.d, "in"), (gpif.d, "out"), - (gpif.ctl, "in"), (gpif.adr, "out"), - (gpif.slwr, "out"), (gpif.sloe, "out"), - (gpif.slrd, "out"), (gpif.pktend, "out")]: - if len(i) > 1: - q = "(*)" - else: - q = "" - self.add_platform_command(""" -INST "{i}%s" TNM = gpif_net_%s; -""" % (q, d), i=i) - self.add_platform_command(""" -NET "{ifclk}" TNM_NET = "GRPifclk"; -TIMESPEC "TSifclk" = PERIOD "GRPifclk" 20833 ps HIGH 50%; -TIMEGRP "gpif_net_in" OFFSET = IN 5 ns VALID 10 ns BEFORE "{ifclk}" RISING; -TIMEGRP "gpif_net_out" OFFSET = OUT 7 ns AFTER "{ifclk}" RISING; -""", ifclk=ifclk) - except ConstraintError: - pass diff --git a/litex/gen/migen/build/platforms/versa.py b/litex/gen/migen/build/platforms/versa.py deleted file mode 100644 index dc8dd53d..00000000 --- a/litex/gen/migen/build/platforms/versa.py +++ /dev/null @@ -1,96 +0,0 @@ -# This file is Copyright (c) 2013 Florent Kermarrec -# License: BSD - -from migen.build.generic_platform import * -from migen.build.lattice import LatticePlatform -from migen.build.lattice.programmer import LatticeProgrammer - - -_io = [ - ("clk100", 0, Pins("L5"), IOStandard("LVDS25")), - ("rst_n", 0, Pins("A21"), IOStandard("LVCMOS33")), - - ("user_led", 0, Pins("Y20"), IOStandard("LVCMOS33")), - ("user_led", 1, Pins("AA21"), IOStandard("LVCMOS33")), - ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33")), - ("user_led", 3, Pins("U19"), IOStandard("LVCMOS33")), - ("user_led", 4, Pins("W19"), IOStandard("LVCMOS33")), - ("user_led", 5, Pins("V19"), IOStandard("LVCMOS33")), - ("user_led", 6, Pins("AB20"), IOStandard("LVCMOS33")), - ("user_led", 7, Pins("AA20"), IOStandard("LVCMOS33")), - - ("user_dip_btn", 0, Pins("J7"), IOStandard("LVCMOS15")), - ("user_dip_btn", 1, Pins("J6"), IOStandard("LVCMOS15")), - ("user_dip_btn", 2, Pins("H2"), IOStandard("LVCMOS15")), - ("user_dip_btn", 3, Pins("H3"), IOStandard("LVCMOS15")), - ("user_dip_btn", 4, Pins("J3"), IOStandard("LVCMOS15")), - ("user_dip_btn", 5, Pins("K3"), IOStandard("LVCMOS15")), - ("user_dip_btn", 6, Pins("J2"), IOStandard("LVCMOS15")), - ("user_dip_btn", 7, Pins("J1"), IOStandard("LVCMOS15")), - - ("serial", 0, - Subsignal("tx", Pins("B11"), IOStandard("LVCMOS33")), # X4 IO0 - Subsignal("rx", Pins("B12"), IOStandard("LVCMOS33")), # X4 IO1 - ), - - ("eth_clocks", 0, - Subsignal("tx", Pins("C12")), - Subsignal("gtx", Pins("M2")), - Subsignal("rx", Pins("L4")), - IOStandard("LVCMOS33") - ), - ("eth", 0, - Subsignal("rst_n", Pins("L3")), - Subsignal("mdio", Pins("L2")), - Subsignal("mdc", Pins("V4")), - Subsignal("dv", Pins("M1")), - Subsignal("rx_er", Pins("M4")), - Subsignal("rx_data", Pins("M5 N1 N6 P6 T2 R2 P5 P3")), - Subsignal("tx_en", Pins("V3")), - Subsignal("tx_data", Pins("V1 U1 R3 P1 N5 N3 N4 N2")), - Subsignal("col", Pins("R1")), - Subsignal("crs", Pins("P4")), - IOStandard("LVCMOS33") - ), - - ("eth_clocks", 1, - Subsignal("tx", Pins("M21")), - Subsignal("gtx", Pins("M19")), - Subsignal("rx", Pins("N19")), - IOStandard("LVCMOS33") - ), - ("eth", 1, - Subsignal("rst_n", Pins("R21")), - Subsignal("mdio", Pins("U16")), - Subsignal("mdc", Pins("Y18")), - Subsignal("dv", Pins("U15")), - Subsignal("rx_er", Pins("V20")), - Subsignal("rx_data", Pins("AB17 AA17 R19 V21 T17 R18 W21 Y21")), - Subsignal("tx_en", Pins("V22")), - Subsignal("tx_data", Pins("W22 R16 P17 Y22 T21 U22 P20 U20")), - Subsignal("col", Pins("N18")), - Subsignal("crs", Pins("P19")), - IOStandard("LVCMOS33") - ), -] - - -class Platform(LatticePlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - LatticePlatform.__init__(self, "LFE3-35EA-6FN484C", _io) - - def do_finalize(self, fragment): - LatticePlatform.do_finalize(self, fragment) - try: - self.add_period_constraint(self.lookup_request("eth_clocks", 0).rx, 8.0) - except ConstraintError: - pass - try: - self.add_period_constraint(self.lookup_request("eth_clocks", 1).rx, 8.0) - except ConstraintError: - pass - def create_programmer(self): - return LatticeProgrammer() diff --git a/litex/gen/migen/build/platforms/zedboard.py b/litex/gen/migen/build/platforms/zedboard.py deleted file mode 100644 index b5d3dcc2..00000000 --- a/litex/gen/migen/build/platforms/zedboard.py +++ /dev/null @@ -1,145 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -# Bank 34 and 35 voltage depend on J18 jumper setting -_io = [ - ("clk100", 0, Pins("Y9"), IOStandard("LVCMOS33")), - - ("user_btn", 0, Pins("P16"), IOStandard("LVCMOS18")), # center - ("user_btn", 1, Pins("R16"), IOStandard("LVCMOS18")), # down - ("user_btn", 2, Pins("N15"), IOStandard("LVCMOS18")), # left - ("user_btn", 3, Pins("R18"), IOStandard("LVCMOS18")), # right - ("user_btn", 4, Pins("T18"), IOStandard("LVCMOS18")), # up - - ("user_sw", 0, Pins("F22"), IOStandard("LVCMOS18")), - ("user_sw", 1, Pins("G22"), IOStandard("LVCMOS18")), - ("user_sw", 2, Pins("H22"), IOStandard("LVCMOS18")), - ("user_sw", 3, Pins("F21"), IOStandard("LVCMOS18")), - ("user_sw", 4, Pins("H19"), IOStandard("LVCMOS18")), - ("user_sw", 5, Pins("H18"), IOStandard("LVCMOS18")), - ("user_sw", 6, Pins("H17"), IOStandard("LVCMOS18")), - ("user_sw", 7, Pins("M15"), IOStandard("LVCMOS18")), - - ("user_led", 0, Pins("T22"), IOStandard("LVCMOS33")), - ("user_led", 1, Pins("T21"), IOStandard("LVCMOS33")), - ("user_led", 2, Pins("U22"), IOStandard("LVCMOS33")), - ("user_led", 3, Pins("U21"), IOStandard("LVCMOS33")), - ("user_led", 4, Pins("V22"), IOStandard("LVCMOS33")), - ("user_led", 5, Pins("W22"), IOStandard("LVCMOS33")), - ("user_led", 6, Pins("U19"), IOStandard("LVCMOS33")), - ("user_led", 7, Pins("U14"), IOStandard("LVCMOS33")), - - # A - ("pmod", 0, Pins("Y11 AA11 Y10 AA9 AB11 AB10 AB9 AA8"), - IOStandard("LVCMOS33")), - # B - ("pmod", 1, Pins("W12 W11 V10 W8 V12 W10 V9 V8"), - IOStandard("LVCMOS33")), - # C - ("pmod", 2, - Subsignal("n", Pins("AB6 AA4 T6 U4")), - Subsignal("p", Pins("AB7 Y4 R6 T4")), - IOStandard("LVCMOS33")), - # D - ("pmod", 3, - Subsignal("n", Pins("W7 V4 W5 U5")), - Subsignal("p", Pins("V7 V5 W6 U6")), - IOStandard("LVCMOS33")), - - ("audio", 0, - Subsignal("adr", Pins("AB1 Y5")), - Subsignal("gpio", Pins("Y8 AA7 AA6 Y6")), - Subsignal("mclk", Pins("AB2")), - Subsignal("sck", Pins("AB4")), - Subsignal("sda", Pins("AB5")), - IOStandard("LVCMOS33")), - - ("oled", 0, - Subsignal("dc", Pins("U10")), - Subsignal("res", Pins("U9")), - Subsignal("sclk", Pins("AB12")), - Subsignal("sdin", Pins("AA12")), - Subsignal("vbat", Pins("U11")), - Subsignal("vdd", Pins("U12")), - IOStandard("LVCMOS33")), - - ("hdmi", 0, - Subsignal("clk", Pins("W18")), - Subsignal("d", Pins( - "Y13 AA13 AA14 Y14 AB15 AB16 AA16 AB17 " - "AA17 Y15 W13 W15 V15 U17 V14 V13")), - Subsignal("de", Pins("U16")), - Subsignal("hsync", Pins("V17")), - Subsignal("vsync", Pins("W17")), - Subsignal("int", Pins("W16")), - Subsignal("scl", Pins("AA18")), - Subsignal("sda", Pins("Y16")), - Subsignal("spdif", Pins("U15")), - Subsignal("spdifo", Pins("Y18")), - IOStandard("LVCMOS33")), - - ("netic16", 0, - Subsignal("w20", Pins("W20")), - Subsignal("w21", Pins("W21")), - IOStandard("LVCMOS33")), - - ("vga", 0, - Subsignal("r", Pins("V20 U20 V19 V18")), - Subsignal("g", Pins("AB22 AA22 AB21 AA21")), - Subsignal("b", Pins("Y21 Y20 AB20 AB19")), - Subsignal("hsync_n", Pins("AA19")), - Subsignal("vsync_n", Pins("Y19")), - IOStandard("LVCMOS33")), - - ("usb_otg", 0, - Subsignal("vbusoc", Pins("L16")), - Subsignal("reset_n", Pins("G17")), - IOStandard("LVCMOS18")), - - ("pudc_b", 0, Pins("K16"), IOStandard("LVCMOS18")), - - ("xadc", 0, - Subsignal("gio", Pins("H15 R15 K15 J15")), - Subsignal("ad0_n", Pins("E16")), - Subsignal("ad0_p", Pins("F16")), - Subsignal("ad8_n", Pins("D17")), - Subsignal("ad8_p", Pins("D16")), - IOStandard("LVCMOS18")), - - ("fmc_clocks", 0, - Subsignal("clk0_n", Pins("L19")), - Subsignal("clk0_p", Pins("L18")), - Subsignal("clk1_n", Pins("C19")), - Subsignal("clk1_p", Pins("D18")), - IOStandard("LVCMOS18")), - - ("fmc", 0, - Subsignal("scl", Pins("R7")), - Subsignal("sda", Pins("U7")), - - Subsignal("prsnt", Pins("AB14")), - - # 0, 1, 17, 18 can be clock signals - Subsignal("la_n", Pins( - "M20 N20 P18 P22 M22 K18 L22 T17 " - "J22 R21 T19 N18 P21 M17 K20 J17 " - "K21 B20 C20 G16 G21 E20 F19 D15 " - "A19 C22 E18 D21 A17 C18 B15 B17 " - "A22 B22")), - Subsignal("la_p", Pins( - "M19 N19 P17 N22 M21 J18 L21 T16 " - "J21 R20 R19 N17 P20 L17 K19 J16 " - "J20 B19 D20 G15 G20 E19 G19 E15 " - "A18 D22 F18 E21 A16 C17 C15 B16 " - "A21 B21")), - IOStandard("LVCMOS18")), -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc7z020-clg484-1", _io) diff --git a/litex/gen/migen/build/platforms/ztex_115d.py b/litex/gen/migen/build/platforms/ztex_115d.py deleted file mode 100644 index 253a121c..00000000 --- a/litex/gen/migen/build/platforms/ztex_115d.py +++ /dev/null @@ -1,110 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("clk_fx", 0, Pins("L22"), IOStandard("LVCMOS33")), - ("clk_if", 0, Pins("K20"), IOStandard("LVCMOS33")), - ("rst", 0, Pins("A18")), - # PROG_B and DONE: AA1 U16 - - ("fx2", 0, - Subsignal("sloe", Pins("U15"), Drive(12)), # M1 - Subsignal("slrd", Pins("N22"), Drive(12)), - Subsignal("slwr", Pins("M22"), Drive(12)), - Subsignal("pktend", Pins("AB5"), Drive(12)), # CSO - Subsignal("fifoadr", Pins("W17 Y18"), Drive(12)), # CCLK M0 - Subsignal("cont", Pins("G20")), - Subsignal("fd", Pins("Y17 V13 W13 AA8 AB8 W6 Y6 Y9 " - "V21 V22 U20 U22 R20 R22 P18 P19")), - Subsignal("flag", Pins("F20 F19 F18 AB17")), # - - - CSI/MOSI - Subsignal("rdy25", Pins("M21 K21 K22 J21")), - Subsignal("ctl35", Pins("D19 E20 N20")), - Subsignal("int45", Pins("C18 V17")), - Subsignal("pc", Pins("G20 T10 V5 AB9 G19 H20 H19 H18")), - # - DOUT/BUSY INIT_B RDWR_B DO CS CLK DI - IOStandard("LVCMOS33")), - - ("mm", 0, - Subsignal("a", Pins("M20 M19 M18 N19 T19 T21 T22 R19 ", - "P20 P21 P22 J22 H21 H22 G22 F21")), - Subsignal("d", Pins("D20 C20 C19 B21 B20 J19 K19 L19"), Drive(2)), - Subsignal("wr_n", Pins("C22")), - Subsignal("rd_n", Pins("D21")), - Subsignal("psen_n", Pins("D22")), - IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("B22"), Misc("SLEW=QUIETIO")), - Subsignal("rx", Pins("A21"), Misc("PULLDOWN")), - IOStandard("LVCMOS33")), - - ("ddram_clock", 0, - Subsignal("p", Pins("F2"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("n", Pins("F1"), Misc("OUT_TERM=UNTUNED_50")), - IOStandard("SSTL18_II")), - - ("ddram", 0, - Subsignal("dqs", Pins("L3 T2"), IOStandard("SSTL18_II"), # DIFF_ - Misc("IN_TERM=NONE")), - Subsignal("dqs_n", Pins("L1 T1"), IOStandard("SSTL18_II"), # DIFF_ - Misc("IN_TERM=NONE")), - Subsignal("dm", Pins("H1 H2"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("dq", Pins("M1 M2 J1 K2 J3 K1 N3 N1 " - "U1 U3 P1 R3 P2 R1 V2 V1"), Misc("IN_TERM=NONE")), - Subsignal("ras_n", Pins("N4"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("cas_n", Pins("P3"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("a", Pins("M5 K6 B1 J4 L4 K3 M4 K5 G3 G1 K4 C3 C1"), - Misc("OUT_TERM=UNTUNED_50")), - Subsignal("ba", Pins("E3 E1 D1"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("cke", Pins("J6"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("cs_n", Pins("H6")), # NC! - Subsignal("odt", Pins("M3"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("we_n", Pins("D2")), - Subsignal("rzq", Pins("AA2")), - Subsignal("zio", Pins("Y2")), - IOStandard("SSTL18_II")), - - ("i2c", 0, - Subsignal("scl", Pins("F22")), - Subsignal("sda", Pins("E22")), - IOStandard("LVCMOS33")), - - ("sd", 0, - Subsignal("sck", Pins("H11")), - Subsignal("d3", Pins("H14")), - Subsignal("d", Pins("P10")), - Subsignal("d1", Pins("T18")), - Subsignal("d2", Pins("R17")), - Subsignal("cmd", Pins("H13")), - IOStandard("LVCMOS33")), - -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk_if" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx150-3csg484", _io) - self.add_platform_command(""" -CONFIG VCCAUX = "2.5"; -""") - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - clk_if = self.lookup_request("clk_if") - clk_fx = self.lookup_request("clk_fx") - self.add_platform_command(""" -NET "{clk_if}" TNM_NET = "GRPclk_if"; -NET "{clk_fx}" TNM_NET = "GRPclk_fx"; -TIMESPEC "TSclk_fx" = PERIOD "GRPclk_fx" 20.83333 ns HIGH 50%; -TIMESPEC "TSclk_if" = PERIOD "GRPclk_if" 20 ns HIGH 50%; -TIMESPEC "TSclk_fx2if" = FROM "GRPclk_fx" TO "GRPclk_if" 3 ns DATAPATHONLY; -TIMESPEC "TSclk_if2fx" = FROM "GRPclk_if" TO "GRPclk_fx" 3 ns DATAPATHONLY; -""", clk_if=clk_if, clk_fx=clk_fx) - except ConstraintError: - pass diff --git a/litex/gen/migen/build/sim/__init__.py b/litex/gen/migen/build/sim/__init__.py deleted file mode 100644 index adbba1c4..00000000 --- a/litex/gen/migen/build/sim/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from migen.build.sim.platform import SimPlatform diff --git a/litex/gen/migen/build/xilinx/__init__.py b/litex/gen/migen/build/xilinx/__init__.py deleted file mode 100644 index 4120abb8..00000000 --- a/litex/gen/migen/build/xilinx/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from migen.build.xilinx.platform import XilinxPlatform -from migen.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept diff --git a/litex/gen/migen/build/xilinx/vivado.py b/litex/gen/migen/build/xilinx/vivado.py deleted file mode 100644 index c1a54a41..00000000 --- a/litex/gen/migen/build/xilinx/vivado.py +++ /dev/null @@ -1,138 +0,0 @@ -# This file is Copyright (c) 2014 Florent Kermarrec -# License: BSD - -import os -import subprocess -import sys - -from migen.fhdl.structure import _Fragment -from migen.build.generic_platform import * -from migen.build import tools -from migen.build.xilinx import common - - -def _format_constraint(c): - if isinstance(c, Pins): - return "set_property LOC " + c.identifiers[0] - elif isinstance(c, IOStandard): - return "set_property IOSTANDARD " + c.name - elif isinstance(c, Drive): - return "set_property DRIVE " + str(c.strength) - elif isinstance(c, Misc): - return "set_property " + c.misc.replace("=", " ") - else: - raise ValueError("unknown constraint {}".format(c)) - - -def _format_xdc(signame, resname, *constraints): - fmt_c = [_format_constraint(c) for c in constraints] - fmt_r = resname[0] + ":" + str(resname[1]) - if resname[2] is not None: - fmt_r += "." + resname[2] - r = " ## {}\n".format(fmt_r) - for c in fmt_c: - r += c + " [get_ports " + signame + "]\n" - return r - - -def _build_xdc(named_sc, named_pc): - r = "" - for sig, pins, others, resname in named_sc: - if len(pins) > 1: - for i, p in enumerate(pins): - r += _format_xdc(sig + "[" + str(i) + "]", resname, Pins(p), *others) - elif pins: - r += _format_xdc(sig, resname, Pins(pins[0]), *others) - else: - r += _format_xdc(sig, resname, *others) - if named_pc: - r += "\n" + "\n\n".join(named_pc) - return r - - -def _run_vivado(build_name, vivado_path, source, ver=None): - if sys.platform == "win32" or sys.platform == "cygwin": - build_script_contents = "REM Autogenerated by Migen\n" - build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" - build_script_file = "build_" + build_name + ".bat" - tools.write_to_file(build_script_file, build_script_contents) - r = subprocess.call([build_script_file]) - else: - build_script_contents = "# Autogenerated by Migen\nset -e\n" - settings = common.settings(vivado_path, ver) - build_script_contents += "source " + settings + "\n" - build_script_contents += "vivado -mode batch -source " + build_name + ".tcl\n" - build_script_file = "build_" + build_name + ".sh" - tools.write_to_file(build_script_file, build_script_contents) - r = subprocess.call(["bash", build_script_file]) - - if r != 0: - raise OSError("Subprocess failed") - - -class XilinxVivadoToolchain: - def __init__(self): - self.bitstream_commands = [] - self.additional_commands = [] - self.pre_synthesis_commands = [] - self.with_phys_opt = False - - def _build_batch(self, platform, sources, build_name): - tcl = [] - for filename, language, library in sources: - filename_tcl = "{" + filename + "}" - tcl.append("add_files " + filename_tcl) - tcl.append("set_property library {} [get_files {}]" - .format(library, filename_tcl)) - - tcl.append("read_xdc {}.xdc".format(build_name)) - tcl.extend(c.format(build_name=build_name) for c in self.pre_synthesis_commands) - tcl.append("synth_design -top top -part {} -include_dirs {{{}}}".format(platform.device, " ".join(platform.verilog_include_paths))) - tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_synth.rpt".format(build_name)) - tcl.append("report_utilization -file {}_utilization_synth.rpt".format(build_name)) - tcl.append("place_design") - if self.with_phys_opt: - tcl.append("phys_opt_design -directive AddRetime") - tcl.append("report_utilization -hierarchical -file {}_utilization_hierarchical_place.rpt".format(build_name)) - tcl.append("report_utilization -file {}_utilization_place.rpt".format(build_name)) - tcl.append("report_io -file {}_io.rpt".format(build_name)) - tcl.append("report_control_sets -verbose -file {}_control_sets.rpt".format(build_name)) - tcl.append("report_clock_utilization -file {}_clock_utilization.rpt".format(build_name)) - tcl.append("route_design") - tcl.append("report_route_status -file {}_route_status.rpt".format(build_name)) - tcl.append("report_drc -file {}_drc.rpt".format(build_name)) - tcl.append("report_timing_summary -max_paths 10 -file {}_timing.rpt".format(build_name)) - tcl.append("report_power -file {}_power.rpt".format(build_name)) - for bitstream_command in self.bitstream_commands: - tcl.append(bitstream_command.format(build_name=build_name)) - tcl.append("write_bitstream -force {}.bit ".format(build_name)) - for additional_command in self.additional_commands: - tcl.append(additional_command.format(build_name=build_name)) - tcl.append("quit") - tools.write_to_file(build_name + ".tcl", "\n".join(tcl)) - - def build(self, platform, fragment, build_dir="build", build_name="top", - toolchain_path="/opt/Xilinx/Vivado", source=True, run=True): - tools.mkdir_noerror(build_dir) - os.chdir(build_dir) - - if not isinstance(fragment, _Fragment): - fragment = fragment.get_fragment() - platform.finalize(fragment) - v_output = platform.get_verilog(fragment) - named_sc, named_pc = platform.resolve_signals(v_output.ns) - v_file = build_name + ".v" - v_output.write(v_file) - sources = platform.sources | {(v_file, "verilog", "work")} - self._build_batch(platform, sources, build_name) - tools.write_to_file(build_name + ".xdc", _build_xdc(named_sc, named_pc)) - if run: - _run_vivado(build_name, toolchain_path, source) - - os.chdir("..") - - return v_output.ns - - def add_period_constraint(self, platform, clk, period): - platform.add_platform_command("""create_clock -name {clk} -period """ + \ - str(period) + """ [get_ports {clk}]""", clk=clk) diff --git a/litex/gen/migen/fhdl/bitcontainer.py b/litex/gen/migen/fhdl/bitcontainer.py deleted file mode 100644 index 15a68d0b..00000000 --- a/litex/gen/migen/fhdl/bitcontainer.py +++ /dev/null @@ -1,121 +0,0 @@ -from migen.fhdl import structure as f - - -__all__ = ["log2_int", "bits_for", "value_bits_sign"] - - -def log2_int(n, need_pow2=True): - l = 1 - r = 0 - while l < n: - l *= 2 - r += 1 - if need_pow2 and l != n: - raise ValueError("Not a power of 2") - return r - - -def bits_for(n, require_sign_bit=False): - if n > 0: - r = log2_int(n + 1, False) - else: - require_sign_bit = True - r = log2_int(-n, False) - if require_sign_bit: - r += 1 - return r - - -def value_bits_sign(v): - """Bit length and signedness of a value. - - Parameters - ---------- - v : Value - - Returns - ------- - int, bool - Number of bits required to store `v` or available in `v`, followed by - whether `v` has a sign bit (included in the bit count). - - Examples - -------- - >>> value_bits_sign(f.Signal(8)) - 8, False - >>> value_bits_sign(C(0xaa)) - 8, False - """ - if isinstance(v, (f.Constant, f.Signal)): - return v.nbits, v.signed - elif isinstance(v, (f.ClockSignal, f.ResetSignal)): - return 1, False - elif isinstance(v, f._Operator): - obs = list(map(value_bits_sign, v.operands)) - if v.op == "+" or v.op == "-": - if not obs[0][1] and not obs[1][1]: - # both operands unsigned - return max(obs[0][0], obs[1][0]) + 1, False - elif obs[0][1] and obs[1][1]: - # both operands signed - return max(obs[0][0], obs[1][0]) + 1, True - elif not obs[0][1] and obs[1][1]: - # first operand unsigned (add sign bit), second operand signed - return max(obs[0][0] + 1, obs[1][0]) + 1, True - else: - # first signed, second operand unsigned (add sign bit) - return max(obs[0][0], obs[1][0] + 1) + 1, True - elif v.op == "*": - if not obs[0][1] and not obs[1][1]: - # both operands unsigned - return obs[0][0] + obs[1][0], False - elif obs[0][1] and obs[1][1]: - # both operands signed - return obs[0][0] + obs[1][0] - 1, True - else: - # one operand signed, the other unsigned (add sign bit) - return obs[0][0] + obs[1][0] + 1 - 1, True - elif v.op == "<<<": - if obs[1][1]: - extra = 2**(obs[1][0] - 1) - 1 - else: - extra = 2**obs[1][0] - 1 - return obs[0][0] + extra, obs[0][1] - elif v.op == ">>>": - if obs[1][1]: - extra = 2**(obs[1][0] - 1) - else: - extra = 0 - return obs[0][0] + extra, obs[0][1] - elif v.op == "&" or v.op == "^" or v.op == "|": - if not obs[0][1] and not obs[1][1]: - # both operands unsigned - return max(obs[0][0], obs[1][0]), False - elif obs[0][1] and obs[1][1]: - # both operands signed - return max(obs[0][0], obs[1][0]), True - elif not obs[0][1] and obs[1][1]: - # first operand unsigned (add sign bit), second operand signed - return max(obs[0][0] + 1, obs[1][0]), True - else: - # first signed, second operand unsigned (add sign bit) - return max(obs[0][0], obs[1][0] + 1), True - elif v.op == "<" or v.op == "<=" or v.op == "==" or v.op == "!=" \ - or v.op == ">" or v.op == ">=": - return 1, False - elif v.op == "~": - return obs[0] - else: - raise TypeError - elif isinstance(v, f._Slice): - return v.stop - v.start, value_bits_sign(v.value)[1] - elif isinstance(v, f.Cat): - return sum(value_bits_sign(sv)[0] for sv in v.l), False - elif isinstance(v, f.Replicate): - return (value_bits_sign(v.v)[0])*v.n, False - elif isinstance(v, f._ArrayProxy): - bsc = list(map(value_bits_sign, v.choices)) - return max(bs[0] for bs in bsc), any(bs[1] for bs in bsc) - else: - raise TypeError("Can not calculate bit length of {} {}".format( - type(v), v)) diff --git a/litex/gen/migen/fhdl/edif.py b/litex/gen/migen/fhdl/edif.py deleted file mode 100644 index f6d7deb0..00000000 --- a/litex/gen/migen/fhdl/edif.py +++ /dev/null @@ -1,213 +0,0 @@ -from collections import OrderedDict, namedtuple - -from migen.fhdl.structure import * -from migen.fhdl.namer import build_namespace -from migen.fhdl.tools import list_special_ios -from migen.fhdl.structure import _Fragment -from migen.fhdl.conv_output import ConvOutput - - -_Port = namedtuple("_Port", "name direction") -_Cell = namedtuple("_Cell", "name ports") -_Property = namedtuple("_Property", "name value") -_Instance = namedtuple("_Instance", "name cell properties") -_NetBranch = namedtuple("_NetBranch", "portname instancename") - - -def _write_cells(cells): - r = "" - for cell in cells: - r += """ - (cell {0.name} - (cellType GENERIC) - (view view_1 - (viewType NETLIST) - (interface""".format(cell) - for port in cell.ports: - r += """ - (port {0.name} (direction {0.direction}))""".format(port) - r += """ - ) - ) - )""" - return r - - -def _write_io(ios): - r = "" - for s in ios: - r += """ - (port {0.name} (direction {0.direction}))""".format(s) - return r - - -def _write_instantiations(instances, cell_library): - instantiations = "" - for instance in instances: - instantiations += """ - (instance {0.name} - (viewRef view_1 (cellRef {0.cell} (libraryRef {1})))""".format(instance, cell_library) - for prop in instance.properties: - instantiations += """ - (property {0} (string "{1}"))""".format(prop.name, prop.value) - instantiations += """ - )""" - return instantiations - - -def _write_connections(connections): - r = "" - for netname, branches in connections.items(): - r += """ - (net {0} - (joined""".format(netname) - for branch in branches: - r += """ - (portRef {0}{1})""".format(branch.portname, "" if branch.instancename == "" else " (instanceRef {})".format(branch.instancename)) - r += """ - ) - )""" - return r - - -def _write_edif(cells, ios, instances, connections, cell_library, design_name, part, vendor): - r = """(edif {0} - (edifVersion 2 0 0) - (edifLevel 0) - (keywordMap (keywordLevel 0)) - (external {1} - (edifLevel 0) - (technology (numberDefinition))""".format(design_name, cell_library) - r += _write_cells(cells) - r += """ - ) - (library {0}_lib - (edifLevel 0) - (technology (numberDefinition)) - (cell {0} - (cellType GENERIC) - (view view_1 - (viewType NETLIST) - (interface""".format(design_name) - r += _write_io(ios) - r += """ - (designator "{0}") - ) - (contents""".format(part) - r += _write_instantiations(instances, cell_library) - r += _write_connections(connections) - r += """ - ) - ) - ) - ) - (design {0} - (cellRef {0} (libraryRef {0}_lib)) - (property PART (string "{1}") (owner "{2}")) - ) -)""".format(design_name, part, vendor) - - return r - - -def _generate_cells(f): - cell_dict = OrderedDict() - for special in f.specials: - if isinstance(special, Instance): - port_list = [] - for port in special.items: - if isinstance(port, Instance.Input): - port_list.append(_Port(port.name, "INPUT")) - elif isinstance(port, Instance.Output): - port_list.append(_Port(port.name, "OUTPUT")) - elif isinstance(port, Instance.InOut): - port_list.append(_Port(port.name, "INOUT")) - elif isinstance(port, Instance.Parameter): - pass - else: - raise NotImplementedError("Unsupported instance item") - if special.of in cell_dict: - if set(port_list) != set(cell_dict[special.of]): - raise ValueError("All instances must have the same ports for EDIF conversion") - else: - cell_dict[special.of] = port_list - else: - raise ValueError("EDIF conversion can only handle synthesized fragments") - return [_Cell(k, v) for k, v in cell_dict.items()] - - -def _generate_instances(f, ns): - instances = [] - for special in f.specials: - if isinstance(special, Instance): - props = [] - for prop in special.items: - if isinstance(prop, Instance.Input): - pass - elif isinstance(prop, Instance.Output): - pass - elif isinstance(prop, Instance.InOut): - pass - elif isinstance(prop, Instance.Parameter): - props.append(_Property(name=prop.name, value=prop.value)) - else: - raise NotImplementedError("Unsupported instance item") - instances.append(_Instance(name=ns.get_name(special), cell=special.of, properties=props)) - else: - raise ValueError("EDIF conversion can only handle synthesized fragments") - return instances - - -def _generate_ios(f, ios, ns): - outs = list_special_ios(f, False, True, False) - inouts = list_special_ios(f, False, False, True) - r = [] - for io in ios: - direction = "OUTPUT" if io in outs else "INOUT" if io in inouts else "INPUT" - r.append(_Port(name=ns.get_name(io), direction=direction)) - return r - - -def _generate_connections(f, ios, ns): - r = OrderedDict() - for special in f.specials: - if isinstance(special, Instance): - instname = ns.get_name(special) - for port in special.items: - if isinstance(port, Instance._IO): - s = ns.get_name(port.expr) - if s not in r: - r[s] = [] - r[s].append(_NetBranch(portname=port.name, instancename=instname)) - elif isinstance(port, Instance.Parameter): - pass - else: - raise NotImplementedError("Unsupported instance item") - else: - raise ValueError("EDIF conversion can only handle synthesized fragments") - for s in ios: - io = ns.get_name(s) - if io not in r: - r[io] = [] - r[io].append(_NetBranch(portname=io, instancename="")) - return r - - -def convert(f, ios, cell_library, vendor, device, name="top"): - if not isinstance(f, _Fragment): - f = f.get_fragment() - if f.comb != [] or f.sync != {}: - raise ValueError("EDIF conversion can only handle synthesized fragments") - if ios is None: - ios = set() - cells = _generate_cells(f) - ns = build_namespace(list_special_ios(f, True, True, True)) - instances = _generate_instances(f, ns) - inouts = _generate_ios(f, ios, ns) - connections = _generate_connections(f, ios, ns) - src = _write_edif(cells, inouts, instances, connections, cell_library, name, device, vendor) - - r = ConvOutput() - r.set_main_source(src) - r.ns = ns - return r diff --git a/litex/gen/migen/fhdl/module.py b/litex/gen/migen/fhdl/module.py deleted file mode 100644 index 7a209933..00000000 --- a/litex/gen/migen/fhdl/module.py +++ /dev/null @@ -1,185 +0,0 @@ -import collections -from itertools import combinations - -from migen.util.misc import flat_iteration -from migen.fhdl.structure import * -from migen.fhdl.structure import _Fragment -from migen.fhdl.tools import rename_clock_domain - - -__all__ = ["Module", "FinalizeError"] - - -class FinalizeError(Exception): - pass - - -def _flat_list(e): - if isinstance(e, collections.Iterable): - return flat_iteration(e) - else: - return [e] - - -class _ModuleProxy: - def __init__(self, fm): - object.__setattr__(self, "_fm", fm) - - -class _ModuleComb(_ModuleProxy): - def __iadd__(self, other): - self._fm._fragment.comb += _flat_list(other) - return self - - -def _cd_append(d, key, statements): - try: - l = d[key] - except KeyError: - l = [] - d[key] = l - l += _flat_list(statements) - - -class _ModuleSyncCD: - def __init__(self, fm, cd): - self._fm = fm - self._cd = cd - - def __iadd__(self, other): - _cd_append(self._fm._fragment.sync, self._cd, other) - return self - - -class _ModuleSync(_ModuleProxy): - def __iadd__(self, other): - _cd_append(self._fm._fragment.sync, "sys", other) - return self - - def __getattr__(self, name): - return _ModuleSyncCD(self._fm, name) - - def __setattr__(self, name, value): - if not isinstance(value, _ModuleSyncCD): - raise AttributeError("Attempted to assign sync property - use += instead") - - -# _ModuleForwardAttr enables user classes to do e.g.: -# self.subm.foobar = SomeModule() -# and then access the submodule with self.foobar. -class _ModuleForwardAttr: - def __setattr__(self, name, value): - self.__iadd__(value) - setattr(self._fm, name, value) - - -class _ModuleSpecials(_ModuleProxy, _ModuleForwardAttr): - def __iadd__(self, other): - self._fm._fragment.specials |= set(_flat_list(other)) - return self - - -class _ModuleSubmodules(_ModuleProxy): - def __setattr__(self, name, value): - self._fm._submodules += [(name, e) for e in _flat_list(value)] - setattr(self._fm, name, value) - - def __iadd__(self, other): - self._fm._submodules += [(None, e) for e in _flat_list(other)] - return self - - -class _ModuleClockDomains(_ModuleProxy, _ModuleForwardAttr): - def __iadd__(self, other): - self._fm._fragment.clock_domains += _flat_list(other) - return self - - -class Module: - def get_fragment(self): - assert(not self.get_fragment_called) - self.get_fragment_called = True - self.finalize() - return self._fragment - - def __getattr__(self, name): - if name == "comb": - return _ModuleComb(self) - elif name == "sync": - return _ModuleSync(self) - elif name == "specials": - return _ModuleSpecials(self) - elif name == "submodules": - return _ModuleSubmodules(self) - elif name == "clock_domains": - return _ModuleClockDomains(self) - - # hack to have initialized regular attributes without using __init__ - # (which would require derived classes to call it) - elif name == "finalized": - self.finalized = False - return self.finalized - elif name == "_fragment": - self._fragment = _Fragment() - return self._fragment - elif name == "_submodules": - self._submodules = [] - return self._submodules - elif name == "_clock_domains": - self._clock_domains = [] - return self._clock_domains - elif name == "get_fragment_called": - self.get_fragment_called = False - return self.get_fragment_called - - else: - raise AttributeError("'"+self.__class__.__name__+"' object has no attribute '"+name+"'") - - def __setattr__(self, name, value): - if name in ["comb", "sync", "specials", "submodules", "clock_domains"]: - if not isinstance(value, _ModuleProxy): - raise AttributeError("Attempted to assign special Module property - use += instead") - else: - object.__setattr__(self, name, value) - - def _collect_submodules(self): - r = [] - for name, submodule in self._submodules: - if not submodule.get_fragment_called: - r.append((name, submodule.get_fragment())) - return r - - def finalize(self, *args, **kwargs): - if not self.finalized: - self.finalized = True - # finalize existing submodules before finalizing us - subfragments = self._collect_submodules() - self.do_finalize(*args, **kwargs) - # finalize submodules created by do_finalize - subfragments += self._collect_submodules() - # resolve clock domain name conflicts - needs_renaming = set() - for (mod_name1, f1), (mod_name2, f2) in combinations(subfragments, 2): - f1_names = set(cd.name for cd in f1.clock_domains) - f2_names = set(cd.name for cd in f2.clock_domains) - common_names = f1_names & f2_names - if common_names: - if mod_name1 is None or mod_name2 is None: - raise ValueError("Multiple submodules with local clock domains cannot be anonymous") - if mod_name1 == mod_name2: - raise ValueError("Multiple submodules with local clock domains cannot have the same name") - needs_renaming |= common_names - for mod_name, f in subfragments: - for cd in f.clock_domains: - if cd.name in needs_renaming: - rename_clock_domain(f, cd.name, mod_name + "_" + cd.name) - # sum subfragments - for mod_name, f in subfragments: - self._fragment += f - - def do_finalize(self): - pass - - def do_exit(self, *args, **kwargs): - for name, submodule in self._submodules: - submodule.do_exit(*args, **kwargs) diff --git a/litex/gen/migen/fhdl/simplify.py b/litex/gen/migen/fhdl/simplify.py deleted file mode 100644 index dba41beb..00000000 --- a/litex/gen/migen/fhdl/simplify.py +++ /dev/null @@ -1,114 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.specials import Memory, _MemoryPort, WRITE_FIRST, NO_CHANGE -from migen.fhdl.decorators import ModuleTransformer -from migen.util.misc import gcd_multiple - - -class FullMemoryWE(ModuleTransformer): - def __init__(self): - self.replacments = dict() - - def transform_fragment(self, i, f): - newspecials = set() - - for orig in f.specials: - if not isinstance(orig, Memory): - newspecials.add(orig) - continue - global_granularity = gcd_multiple([p.we_granularity if p.we_granularity else orig.width for p in orig.ports]) - if global_granularity == orig.width: - newspecials.add(orig) # nothing to do - else: - newmems = [] - for i in range(orig.width//global_granularity): - if orig.init is None: - newinit = None - else: - newinit = [(v >> i*global_granularity) & (2**global_granularity - 1) for v in orig.init] - newmem = Memory(global_granularity, orig.depth, newinit, orig.name_override + "_grain" + str(i)) - newspecials.add(newmem) - newmems.append(newmem) - for port in orig.ports: - port_granularity = port.we_granularity if port.we_granularity else orig.width - newport = _MemoryPort( - adr=port.adr, - - dat_r=port.dat_r[i*global_granularity:(i+1)*global_granularity] if port.dat_r is not None else None, - we=port.we[i*global_granularity//port_granularity] if port.we is not None else None, - dat_w=port.dat_w[i*global_granularity:(i+1)*global_granularity] if port.dat_w is not None else None, - - async_read=port.async_read, - re=port.re, - we_granularity=0, - mode=port.mode, - clock_domain=port.clock.cd) - newmem.ports.append(newport) - newspecials.add(newport) - self.replacments[orig] = newmems - - f.specials = newspecials - - -class MemoryToArray(ModuleTransformer): - def __init__(self): - self.replacements = dict() - - def transform_fragment(self, i, f): - newspecials = set() - - for mem in f.specials: - if not isinstance(mem, Memory): - newspecials.add(mem) - continue - - storage = Array() - self.replacements[mem] = storage - init = [] - if mem.init is not None: - init = mem.init - for d in init: - mem_storage = Signal(mem.width, reset=d) - storage.append(mem_storage) - for _ in range(mem.depth-len(init)): - mem_storage = Signal(mem.width) - storage.append(mem_storage) - - for port in mem.ports: - if port.we_granularity: - raise NotImplementedError - try: - sync = f.sync[port.clock.cd] - except KeyError: - sync = f.sync[port.clock.cd] = [] - - # read - if port.async_read: - f.comb.append(port.dat_r.eq(storage[port.adr])) - else: - if port.mode == WRITE_FIRST and port.we is not None: - adr_reg = Signal.like(port.adr) - rd_stmt = adr_reg.eq(port.adr) - f.comb.append(port.dat_r.eq(storage[adr_reg])) - elif port.mode == NO_CHANGE and port.we is not None: - rd_stmt = If(~port.we, port.dat_r.eq(storage[port.adr])) - else: # READ_FIRST or port.we is None, simplest case - rd_stmt = port.dat_r.eq(storage[port.adr]) - if port.re is None: - sync.append(rd_stmt) - else: - sync.append(If(port.re, rd_stmt)) - - # write - if port.we is not None: - if port.we_granularity: - n = mem.width//port.we_granularity - for i in range(n): - m = i*port.we_granularity - M = (i+1)*port.we_granularity - sync.append(If(port.we[i], - storage[port.adr][m:M].eq(port.dat_w))) - else: - sync.append(If(port.we, - storage[port.adr].eq(port.dat_w))) - - f.specials = newspecials diff --git a/litex/gen/migen/fhdl/specials.py b/litex/gen/migen/fhdl/specials.py deleted file mode 100644 index bd3e1bf5..00000000 --- a/litex/gen/migen/fhdl/specials.py +++ /dev/null @@ -1,360 +0,0 @@ -from operator import itemgetter - -from migen.fhdl.structure import * -from migen.fhdl.structure import _Value -from migen.fhdl.bitcontainer import bits_for, value_bits_sign -from migen.fhdl.tools import * -from migen.fhdl.tracer import get_obj_var_name -from migen.fhdl.verilog import _printexpr as verilog_printexpr - - -__all__ = ["TSTriple", "Instance", "Memory", - "READ_FIRST", "WRITE_FIRST", "NO_CHANGE"] - - -class Special(DUID): - def iter_expressions(self): - for x in []: - yield x - - def rename_clock_domain(self, old, new): - for obj, attr, direction in self.iter_expressions(): - rename_clock_domain_expr(getattr(obj, attr), old, new) - - def list_clock_domains(self): - r = set() - for obj, attr, direction in self.iter_expressions(): - r |= list_clock_domains_expr(getattr(obj, attr)) - return r - - def list_ios(self, ins, outs, inouts): - r = set() - for obj, attr, direction in self.iter_expressions(): - if (direction == SPECIAL_INPUT and ins) \ - or (direction == SPECIAL_OUTPUT and outs) \ - or (direction == SPECIAL_INOUT and inouts): - signals = list_signals(getattr(obj, attr)) - r.update(signals) - return r - - -class Tristate(Special): - def __init__(self, target, o, oe, i=None): - Special.__init__(self) - self.target = wrap(target) - self.o = wrap(o) - self.oe = wrap(oe) - self.i = wrap(i) if i is not None else None - - def iter_expressions(self): - for attr, target_context in [ - ("target", SPECIAL_INOUT), - ("o", SPECIAL_INPUT), - ("oe", SPECIAL_INPUT), - ("i", SPECIAL_OUTPUT)]: - if getattr(self, attr) is not None: - yield self, attr, target_context - - @staticmethod - def emit_verilog(tristate, ns, add_data_file): - def pe(e): - return verilog_printexpr(ns, e)[0] - w, s = value_bits_sign(tristate.target) - r = "assign " + pe(tristate.target) + " = " \ - + pe(tristate.oe) + " ? " + pe(tristate.o) \ - + " : " + str(w) + "'bz;\n" - if tristate.i is not None: - r += "assign " + pe(tristate.i) + " = " + pe(tristate.target) + ";\n" - r += "\n" - return r - - -class TSTriple: - def __init__(self, bits_sign=None, min=None, max=None, reset_o=0, reset_oe=0): - self.o = Signal(bits_sign, min=min, max=max, reset=reset_o) - self.oe = Signal(reset=reset_oe) - self.i = Signal(bits_sign, min=min, max=max) - - def get_tristate(self, target): - return Tristate(target, self.o, self.oe, self.i) - - -class Instance(Special): - class _IO: - def __init__(self, name, expr=None): - self.name = name - if expr is None: - expr = Signal() - self.expr = wrap(expr) - class Input(_IO): - pass - class Output(_IO): - pass - class InOut(_IO): - pass - class Parameter: - def __init__(self, name, value): - self.name = name - if isinstance(value, (int, bool)): - value = Constant(value) - self.value = value - class PreformattedParam(str): - pass - - def __init__(self, of, *items, name="", synthesis_directive=None, **kwargs): - Special.__init__(self) - self.of = of - if name: - self.name_override = name - else: - self.name_override = of - self.items = list(items) - self.synthesis_directive = synthesis_directive - for k, v in sorted(kwargs.items(), key=itemgetter(0)): - item_type, item_name = k.split("_", maxsplit=1) - item_class = { - "i": Instance.Input, - "o": Instance.Output, - "io": Instance.InOut, - "p": Instance.Parameter - }[item_type] - self.items.append(item_class(item_name, v)) - - def get_io(self, name): - for item in self.items: - if isinstance(item, Instance._IO) and item.name == name: - return item.expr - - def iter_expressions(self): - for item in self.items: - if isinstance(item, Instance.Input): - yield item, "expr", SPECIAL_INPUT - elif isinstance(item, Instance.Output): - yield item, "expr", SPECIAL_OUTPUT - elif isinstance(item, Instance.InOut): - yield item, "expr", SPECIAL_INOUT - - @staticmethod - def emit_verilog(instance, ns, add_data_file): - r = instance.of + " " - parameters = list(filter(lambda i: isinstance(i, Instance.Parameter), instance.items)) - if parameters: - r += "#(\n" - firstp = True - for p in parameters: - if not firstp: - r += ",\n" - firstp = False - r += "\t." + p.name + "(" - if isinstance(p.value, Constant): - r += verilog_printexpr(ns, p.value)[0] - elif isinstance(p.value, float): - r += str(p.value) - elif isinstance(p.value, Instance.PreformattedParam): - r += p.value - elif isinstance(p.value, str): - r += "\"" + p.value + "\"" - else: - raise TypeError - r += ")" - r += "\n) " - r += ns.get_name(instance) - if parameters: r += " " - r += "(\n" - firstp = True - for p in instance.items: - if isinstance(p, Instance._IO): - name_inst = p.name - name_design = verilog_printexpr(ns, p.expr)[0] - if not firstp: - r += ",\n" - firstp = False - r += "\t." + name_inst + "(" + name_design + ")" - if not firstp: - r += "\n" - if instance.synthesis_directive is not None: - synthesis_directive = "/* synthesis {} */".format(instance.synthesis_directive) - r += ")" + synthesis_directive + ";\n\n" - else: - r += ");\n\n" - return r - - -(READ_FIRST, WRITE_FIRST, NO_CHANGE) = range(3) - - -class _MemoryPort(Special): - def __init__(self, adr, dat_r, we=None, dat_w=None, - async_read=False, re=None, we_granularity=0, mode=WRITE_FIRST, - clock_domain="sys"): - Special.__init__(self) - self.adr = adr - self.dat_r = dat_r - self.we = we - self.dat_w = dat_w - self.async_read = async_read - self.re = re - self.we_granularity = we_granularity - self.mode = mode - self.clock = ClockSignal(clock_domain) - - def iter_expressions(self): - for attr, target_context in [ - ("adr", SPECIAL_INPUT), - ("we", SPECIAL_INPUT), - ("dat_w", SPECIAL_INPUT), - ("re", SPECIAL_INPUT), - ("dat_r", SPECIAL_OUTPUT), - ("clock", SPECIAL_INPUT)]: - yield self, attr, target_context - - @staticmethod - def emit_verilog(port, ns, add_data_file): - return "" # done by parent Memory object - - -class _MemoryLocation(_Value): - def __init__(self, memory, index): - _Value.__init__(self) - self.memory = memory - self.index = wrap(index) - - -class Memory(Special): - def __init__(self, width, depth, init=None, name=None): - Special.__init__(self) - self.width = width - self.depth = depth - self.ports = [] - self.init = init - self.name_override = get_obj_var_name(name, "mem") - - def __getitem__(self, index): - # simulation only - return _MemoryLocation(self, index) - - def get_port(self, write_capable=False, async_read=False, - has_re=False, we_granularity=0, mode=WRITE_FIRST, - clock_domain="sys"): - if we_granularity >= self.width: - we_granularity = 0 - adr = Signal(max=self.depth) - dat_r = Signal(self.width) - if write_capable: - if we_granularity: - we = Signal(self.width//we_granularity) - else: - we = Signal() - dat_w = Signal(self.width) - else: - we = None - dat_w = None - if has_re: - re = Signal() - else: - re = None - mp = _MemoryPort(adr, dat_r, we, dat_w, - async_read, re, we_granularity, mode, - clock_domain) - self.ports.append(mp) - return mp - - @staticmethod - def emit_verilog(memory, ns, add_data_file): - r = "" - def gn(e): - if isinstance(e, Memory): - return ns.get_name(e) - else: - return verilog_printexpr(ns, e)[0] - adrbits = bits_for(memory.depth-1) - - r += "reg [" + str(memory.width-1) + ":0] " \ - + gn(memory) \ - + "[0:" + str(memory.depth-1) + "];\n" - - adr_regs = {} - data_regs = {} - for port in memory.ports: - if not port.async_read: - if port.mode == WRITE_FIRST and port.we is not None: - adr_reg = Signal(name_override="memadr") - r += "reg [" + str(adrbits-1) + ":0] " \ - + gn(adr_reg) + ";\n" - adr_regs[id(port)] = adr_reg - else: - data_reg = Signal(name_override="memdat") - r += "reg [" + str(memory.width-1) + ":0] " \ - + gn(data_reg) + ";\n" - data_regs[id(port)] = data_reg - - for port in memory.ports: - r += "always @(posedge " + gn(port.clock) + ") begin\n" - if port.we is not None: - if port.we_granularity: - n = memory.width//port.we_granularity - for i in range(n): - m = i*port.we_granularity - M = (i+1)*port.we_granularity-1 - sl = "[" + str(M) + ":" + str(m) + "]" - r += "\tif (" + gn(port.we) + "[" + str(i) + "])\n" - r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "]" + sl + " <= " + gn(port.dat_w) + sl + ";\n" - else: - r += "\tif (" + gn(port.we) + ")\n" - r += "\t\t" + gn(memory) + "[" + gn(port.adr) + "] <= " + gn(port.dat_w) + ";\n" - if not port.async_read: - if port.mode == WRITE_FIRST and port.we is not None: - rd = "\t" + gn(adr_regs[id(port)]) + " <= " + gn(port.adr) + ";\n" - else: - bassign = gn(data_regs[id(port)]) + " <= " + gn(memory) + "[" + gn(port.adr) + "];\n" - if port.mode == READ_FIRST or port.we is None: - rd = "\t" + bassign - elif port.mode == NO_CHANGE: - rd = "\tif (!" + gn(port.we) + ")\n" \ - + "\t\t" + bassign - if port.re is None: - r += rd - else: - r += "\tif (" + gn(port.re) + ")\n" - r += "\t" + rd.replace("\n\t", "\n\t\t") - r += "end\n\n" - - for port in memory.ports: - if port.async_read: - r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(port.adr) + "];\n" - else: - if port.mode == WRITE_FIRST and port.we is not None: - r += "assign " + gn(port.dat_r) + " = " + gn(memory) + "[" + gn(adr_regs[id(port)]) + "];\n" - else: - r += "assign " + gn(port.dat_r) + " = " + gn(data_regs[id(port)]) + ";\n" - r += "\n" - - if memory.init is not None: - content = "" - for d in memory.init: - content += "{:x}\n".format(d) - memory_filename = add_data_file(gn(memory) + ".init", content) - - r += "initial begin\n" - r += "\t$readmemh(\"" + memory_filename + "\", " + gn(memory) + ");\n" - r += "end\n\n" - - return r - - -class SynthesisDirective(Special): - def __init__(self, template, **signals): - Special.__init__(self) - self.template = template - self.signals = signals - - @staticmethod - def emit_verilog(directive, ns, add_data_file): - name_dict = dict((k, ns.get_name(sig)) for k, sig in directive.signals.items()) - formatted = directive.template.format(**name_dict) - return "// synthesis " + formatted + "\n" - - -class Keep(SynthesisDirective): - def __init__(self, signal): - SynthesisDirective.__init__(self, "attribute keep of {s} is true", s=signal) diff --git a/litex/gen/migen/fhdl/structure.py b/litex/gen/migen/fhdl/structure.py deleted file mode 100644 index f4250266..00000000 --- a/litex/gen/migen/fhdl/structure.py +++ /dev/null @@ -1,713 +0,0 @@ -import builtins as _builtins -import collections as _collections - -from migen.fhdl import tracer as _tracer -from migen.util.misc import flat_iteration as _flat_iteration - - -class DUID: - """Deterministic Unique IDentifier""" - __next_uid = 0 - def __init__(self): - self.duid = DUID.__next_uid - DUID.__next_uid += 1 - - -class _Value(DUID): - """Base class for operands - - Instances of `_Value` or its subclasses can be operands to - arithmetic, comparison, bitwise, and logic operators. - They can be assigned (:meth:`eq`) or indexed/sliced (using the usual - Python indexing and slicing notation). - - Values created from integers have the minimum bit width to necessary to - represent the integer. - """ - def __bool__(self): - # Special case: Constants and Signals are part of a set or used as - # dictionary keys, and Python needs to check for equality. - if isinstance(self, _Operator) and self.op == "==": - a, b = self.operands - if isinstance(a, Constant) and isinstance(b, Constant): - return a.value == b.value - if isinstance(a, Signal) and isinstance(b, Signal): - return a is b - if (isinstance(a, Constant) and isinstance(b, Signal) - or isinstance(a, Signal) and isinstance(a, Constant)): - return False - raise TypeError("Attempted to convert Migen value to boolean") - - def __invert__(self): - return _Operator("~", [self]) - def __neg__(self): - return _Operator("-", [self]) - - def __add__(self, other): - return _Operator("+", [self, other]) - def __radd__(self, other): - return _Operator("+", [other, self]) - def __sub__(self, other): - return _Operator("-", [self, other]) - def __rsub__(self, other): - return _Operator("-", [other, self]) - def __mul__(self, other): - return _Operator("*", [self, other]) - def __rmul__(self, other): - return _Operator("*", [other, self]) - def __lshift__(self, other): - return _Operator("<<<", [self, other]) - def __rlshift__(self, other): - return _Operator("<<<", [other, self]) - def __rshift__(self, other): - return _Operator(">>>", [self, other]) - def __rrshift__(self, other): - return _Operator(">>>", [other, self]) - def __and__(self, other): - return _Operator("&", [self, other]) - def __rand__(self, other): - return _Operator("&", [other, self]) - def __xor__(self, other): - return _Operator("^", [self, other]) - def __rxor__(self, other): - return _Operator("^", [other, self]) - def __or__(self, other): - return _Operator("|", [self, other]) - def __ror__(self, other): - return _Operator("|", [other, self]) - - def __lt__(self, other): - return _Operator("<", [self, other]) - def __le__(self, other): - return _Operator("<=", [self, other]) - def __eq__(self, other): - return _Operator("==", [self, other]) - def __ne__(self, other): - return _Operator("!=", [self, other]) - def __gt__(self, other): - return _Operator(">", [self, other]) - def __ge__(self, other): - return _Operator(">=", [self, other]) - - def __len__(self): - from migen.fhdl.bitcontainer import value_bits_sign - return value_bits_sign(self)[0] - - def __getitem__(self, key): - n = len(self) - if isinstance(key, int): - if key >= n: - raise IndexError - if key < 0: - key += n - return _Slice(self, key, key+1) - elif isinstance(key, slice): - start, stop, step = key.indices(n) - if step != 1: - return Cat(self[i] for i in range(start, stop, step)) - return _Slice(self, start, stop) - else: - raise TypeError - - def eq(self, r): - """Assignment - - Parameters - ---------- - r : _Value, in - Value to be assigned. - - Returns - ------- - _Assign - Assignment statement that can be used in combinatorial or - synchronous context. - """ - return _Assign(self, r) - - def __hash__(self): - raise TypeError("unhashable type: '{}'".format(type(self).__name__)) - - -def wrap(value): - """Ensures that the passed object is a Migen value. Booleans and integers - are automatically wrapped into ``Constant``.""" - if isinstance(value, (bool, int)): - value = Constant(value) - if not isinstance(value, _Value): - raise TypeError("Object is not a Migen value") - return value - - -class _Operator(_Value): - def __init__(self, op, operands): - _Value.__init__(self) - self.op = op - self.operands = [wrap(o) for o in operands] - - -def Mux(sel, val1, val0): - """Multiplex between two values - - Parameters - ---------- - sel : _Value(1), in - Selector. - val1 : _Value(N), in - val0 : _Value(N), in - Input values. - - Returns - ------- - _Value(N), out - Output `_Value`. If `sel` is asserted, the Mux returns - `val1`, else `val0`. - """ - return _Operator("m", [sel, val1, val0]) - - -class _Slice(_Value): - def __init__(self, value, start, stop): - _Value.__init__(self) - if not isinstance(start, int) or not isinstance(stop, int): - raise TypeError("Slice boundaries must be integers") - self.value = wrap(value) - self.start = start - self.stop = stop - - -class Cat(_Value): - """Concatenate values - - Form a compound `_Value` from several smaller ones by concatenation. - The first argument occupies the lower bits of the result. - The return value can be used on either side of an assignment, that - is, the concatenated value can be used as an argument on the RHS or - as a target on the LHS. If it is used on the LHS, it must solely - consist of `Signal` s, slices of `Signal` s, and other concatenations - meeting these properties. The bit length of the return value is the sum of - the bit lengths of the arguments:: - - len(Cat(args)) == sum(len(arg) for arg in args) - - Parameters - ---------- - *args : _Values or iterables of _Values, inout - `_Value` s to be concatenated. - - Returns - ------- - Cat, inout - Resulting `_Value` obtained by concatentation. - """ - def __init__(self, *args): - _Value.__init__(self) - self.l = [wrap(v) for v in _flat_iteration(args)] - - -class Replicate(_Value): - """Replicate a value - - An input value is replicated (repeated) several times - to be used on the RHS of assignments:: - - len(Replicate(s, n)) == len(s)*n - - Parameters - ---------- - v : _Value, in - Input value to be replicated. - n : int - Number of replications. - - Returns - ------- - Replicate, out - Replicated value. - """ - def __init__(self, v, n): - _Value.__init__(self) - if not isinstance(n, int) or n < 0: - raise TypeError("Replication count must be a positive integer") - self.v = wrap(v) - self.n = n - - -class Constant(_Value): - """A constant, HDL-literal integer `_Value` - - Parameters - ---------- - value : int - bits_sign : int or tuple or None - Either an integer `bits` or a tuple `(bits, signed)` - specifying the number of bits in this `Constant` and whether it is - signed (can represent negative values). `bits_sign` defaults - to the minimum width and signedness of `value`. - """ - def __init__(self, value, bits_sign=None): - from migen.fhdl.bitcontainer import bits_for - - _Value.__init__(self) - - self.value = int(value) - if bits_sign is None: - bits_sign = bits_for(self.value), self.value < 0 - elif isinstance(bits_sign, int): - bits_sign = bits_sign, self.value < 0 - self.nbits, self.signed = bits_sign - if not isinstance(self.nbits, int) or self.nbits <= 0: - raise TypeError("Width must be a strictly positive integer") - - def __hash__(self): - return self.value - - -C = Constant # shorthand - - -class Signal(_Value): - """A `_Value` that can change - - The `Signal` object represents a value that is expected to change - in the circuit. It does exactly what Verilog's `wire` and - `reg` and VHDL's `signal` do. - - A `Signal` can be indexed to access a subset of its bits. Negative - indices (`signal[-1]`) and the extended Python slicing notation - (`signal[start:stop:step]`) are supported. - The indices 0 and -1 are the least and most significant bits - respectively. - - Parameters - ---------- - bits_sign : int or tuple - Either an integer `bits` or a tuple `(bits, signed)` - specifying the number of bits in this `Signal` and whether it is - signed (can represent negative values). `signed` defaults to - `False`. - name : str or None - Name hint for this signal. If `None` (default) the name is - inferred from the variable name this `Signal` is assigned to. - Name collisions are automatically resolved by prepending - names of objects that contain this `Signal` and by - appending integer sequences. - variable : bool - Deprecated. - reset : int - Reset (synchronous) or default (combinatorial) value. - When this `Signal` is assigned to in synchronous context and the - corresponding clock domain is reset, the `Signal` assumes the - given value. When this `Signal` is unassigned in combinatorial - context (due to conditional assignments not being taken), - the `Signal` assumes its `reset` value. Defaults to 0. - name_override : str or None - Do not use the inferred name but the given one. - min : int or None - max : int or None - If `bits_sign` is `None`, the signal bit width and signedness are - determined by the integer range given by `min` (inclusive, - defaults to 0) and `max` (exclusive, defaults to 2). - related : Signal or None - """ - def __init__(self, bits_sign=None, name=None, variable=False, reset=0, name_override=None, min=None, max=None, related=None): - from migen.fhdl.bitcontainer import bits_for - - _Value.__init__(self) - - # determine number of bits and signedness - if bits_sign is None: - if min is None: - min = 0 - if max is None: - max = 2 - max -= 1 # make both bounds inclusive - assert(min < max) - self.signed = min < 0 or max < 0 - self.nbits = _builtins.max(bits_for(min, self.signed), bits_for(max, self.signed)) - else: - assert(min is None and max is None) - if isinstance(bits_sign, tuple): - self.nbits, self.signed = bits_sign - else: - self.nbits, self.signed = bits_sign, False - if not isinstance(self.nbits, int) or self.nbits <= 0: - raise ValueError("Signal width must be a strictly positive integer") - - self.variable = variable # deprecated - self.reset = reset - self.name_override = name_override - self.backtrace = _tracer.trace_back(name) - self.related = related - - def __setattr__(self, k, v): - if k == "reset": - v = wrap(v) - _Value.__setattr__(self, k, v) - - def __repr__(self): - return "" - - @classmethod - def like(cls, other, **kwargs): - """Create Signal based on another. - - Parameters - ---------- - other : _Value - Object to base this Signal on. - - See `migen.fhdl.bitcontainer.value_bits_sign` for details. - """ - from migen.fhdl.bitcontainer import value_bits_sign - return cls(bits_sign=value_bits_sign(other), **kwargs) - - def __hash__(self): - return self.duid - - -class ClockSignal(_Value): - """Clock signal for a given clock domain - - `ClockSignal` s for a given clock domain can be retrieved multiple - times. They all ultimately refer to the same signal. - - Parameters - ---------- - cd : str - Clock domain to obtain a clock signal for. Defaults to `"sys"`. - """ - def __init__(self, cd="sys"): - _Value.__init__(self) - if not isinstance(cd, str): - raise TypeError("Argument of ClockSignal must be a string") - self.cd = cd - - -class ResetSignal(_Value): - """Reset signal for a given clock domain - - `ResetSignal` s for a given clock domain can be retrieved multiple - times. They all ultimately refer to the same signal. - - Parameters - ---------- - cd : str - Clock domain to obtain a reset signal for. Defaults to `"sys"`. - allow_reset_less : bool - If the clock domain is resetless, return 0 instead of reporting an - error. - """ - def __init__(self, cd="sys", allow_reset_less=False): - _Value.__init__(self) - if not isinstance(cd, str): - raise TypeError("Argument of ResetSignal must be a string") - self.cd = cd - self.allow_reset_less = allow_reset_less - - -# statements - - -class _Statement: - pass - - -class _Assign(_Statement): - def __init__(self, l, r): - self.l = wrap(l) - self.r = wrap(r) - - -def _check_statement(s): - if isinstance(s, _collections.Iterable): - return all(_check_statement(ss) for ss in s) - else: - return isinstance(s, _Statement) - - -class If(_Statement): - """Conditional execution of statements - - Parameters - ---------- - cond : _Value(1), in - Condition - *t : Statements - Statements to execute if `cond` is asserted. - - Examples - -------- - >>> a = Signal() - >>> b = Signal() - >>> c = Signal() - >>> d = Signal() - >>> If(a, - ... b.eq(1) - ... ).Elif(c, - ... b.eq(0) - ... ).Else( - ... b.eq(d) - ... ) - """ - def __init__(self, cond, *t): - if not _check_statement(t): - raise TypeError("Not all test body objects are Migen statements") - self.cond = wrap(cond) - self.t = list(t) - self.f = [] - - def Else(self, *f): - """Add an `else` conditional block - - Parameters - ---------- - *f : Statements - Statements to execute if all previous conditions fail. - """ - if not _check_statement(f): - raise TypeError("Not all test body objects are Migen statements") - _insert_else(self, list(f)) - return self - - def Elif(self, cond, *t): - """Add an `else if` conditional block - - Parameters - ---------- - cond : _Value(1), in - Condition - *t : Statements - Statements to execute if previous conditions fail and `cond` - is asserted. - """ - _insert_else(self, [If(cond, *t)]) - return self - - -def _insert_else(obj, clause): - o = obj - while o.f: - assert(len(o.f) == 1) - assert(isinstance(o.f[0], If)) - o = o.f[0] - o.f = clause - - -class Case(_Statement): - """Case/Switch statement - - Parameters - ---------- - test : _Value, in - Selector value used to decide which block to execute - cases : dict - Dictionary of cases. The keys are numeric constants to compare - with `test`. The values are statements to be executed the - corresponding key matches `test`. The dictionary may contain a - string key `"default"` to mark a fall-through case that is - executed if no other key matches. - - Examples - -------- - >>> a = Signal() - >>> b = Signal() - >>> Case(a, { - ... 0: b.eq(1), - ... 1: b.eq(0), - ... "default": b.eq(0), - ... }) - """ - def __init__(self, test, cases): - self.test = wrap(test) - self.cases = dict() - for k, v in cases.items(): - if isinstance(k, (bool, int)): - k = Constant(k) - if (not isinstance(k, Constant) - and not (isinstance(k, str) and k == "default")): - raise TypeError("Case object is not a Migen constant") - if not isinstance(v, _collections.Iterable): - v = [v] - if not _check_statement(v): - raise TypeError("Not all objects for case {} " - "are Migen statements".format(k)) - self.cases[k] = v - - def makedefault(self, key=None): - """Mark a key as the default case - - Deletes/substitutes any previously existing default case. - - Parameters - ---------- - key : int or None - Key to use as default case if no other key matches. - By default, the largest key is the default key. - """ - if key is None: - for choice in self.cases.keys(): - if key is None or choice.value > key.value: - key = choice - self.cases["default"] = self.cases[key] - del self.cases[key] - return self - - -# arrays - - -class _ArrayProxy(_Value): - def __init__(self, choices, key): - _Value.__init__(self) - self.choices = [] - for c in choices: - if isinstance(c, (bool, int)): - c = Constant(c) - self.choices.append(c) - self.key = key - - def __getattr__(self, attr): - return _ArrayProxy([getattr(choice, attr) for choice in self.choices], - self.key) - - def __getitem__(self, key): - return _ArrayProxy([choice.__getitem__(key) for choice in self.choices], - self.key) - - -class Array(list): - """Addressable multiplexer - - An array is created from an iterable of values and indexed using the - usual Python simple indexing notation (no negative indices or - slices). It can be indexed by numeric constants, `_Value` s, or - `Signal` s. - - The result of indexing the array is a proxy for the entry at the - given index that can be used on either RHS or LHS of assignments. - - An array can be indexed multiple times. - - Multidimensional arrays are supported by packing inner arrays into - outer arrays. - - Parameters - ---------- - values : iterable of ints, _Values, Signals - Entries of the array. Each entry can be a numeric constant, a - `Signal` or a `Record`. - - Examples - -------- - >>> a = Array(range(10)) - >>> b = Signal(max=10) - >>> c = Signal(max=10) - >>> b.eq(a[9 - c]) - """ - def __getitem__(self, key): - if isinstance(key, Constant): - return list.__getitem__(self, key.value) - elif isinstance(key, _Value): - return _ArrayProxy(self, key) - else: - return list.__getitem__(self, key) - - -class ClockDomain: - """Synchronous domain - - Parameters - ---------- - name : str or None - Domain name. If None (the default) the name is inferred from the - variable name this `ClockDomain` is assigned to (stripping any - `"cd_"` prefix). - reset_less : bool - The domain does not use a reset signal. Registers within this - domain are still all initialized to their reset state once, e.g. - through Verilog `"initial"` statements. - - Attributes - ---------- - clk : Signal, inout - The clock for this domain. Can be driven or used to drive other - signals (preferably in combinatorial context). - rst : Signal or None, inout - Reset signal for this domain. Can be driven or used to drive. - """ - def __init__(self, name=None, reset_less=False): - self.name = _tracer.get_obj_var_name(name) - if self.name is None: - raise ValueError("Cannot extract clock domain name from code, need to specify.") - if self.name.startswith("cd_"): - self.name = self.name[3:] - if self.name[0].isdigit(): - raise ValueError("Clock domain name cannot start with a number.") - self.clk = Signal(name_override=self.name + "_clk") - if reset_less: - self.rst = None - else: - self.rst = Signal(name_override=self.name + "_rst") - - def rename(self, new_name): - """Rename the clock domain - - Parameters - ---------- - new_name : str - New name - """ - self.name = new_name - self.clk.name_override = new_name + "_clk" - if self.rst is not None: - self.rst.name_override = new_name + "_rst" - - -class _ClockDomainList(list): - def __getitem__(self, key): - if isinstance(key, str): - for cd in self: - if cd.name == key: - return cd - raise KeyError(key) - else: - return list.__getitem__(self, key) - - -(SPECIAL_INPUT, SPECIAL_OUTPUT, SPECIAL_INOUT) = range(3) - - -class _Fragment: - def __init__(self, comb=None, sync=None, specials=None, clock_domains=None): - if comb is None: comb = [] - if sync is None: sync = dict() - if specials is None: specials = set() - if clock_domains is None: clock_domains = _ClockDomainList() - - self.comb = comb - self.sync = sync - self.specials = specials - self.clock_domains = _ClockDomainList(clock_domains) - - def __add__(self, other): - newsync = _collections.defaultdict(list) - for k, v in self.sync.items(): - newsync[k] = v[:] - for k, v in other.sync.items(): - newsync[k].extend(v) - return _Fragment(self.comb + other.comb, newsync, - self.specials | other.specials, - self.clock_domains + other.clock_domains) - - def __iadd__(self, other): - newsync = _collections.defaultdict(list) - for k, v in self.sync.items(): - newsync[k] = v[:] - for k, v in other.sync.items(): - newsync[k].extend(v) - self.comb += other.comb - self.sync = newsync - self.specials |= other.specials - self.clock_domains += other.clock_domains - return self diff --git a/litex/gen/migen/genlib/cdc.py b/litex/gen/migen/genlib/cdc.py deleted file mode 100644 index c5342b7b..00000000 --- a/litex/gen/migen/genlib/cdc.py +++ /dev/null @@ -1,141 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.specials import Special -from migen.fhdl.bitcontainer import value_bits_sign -from migen.genlib.misc import WaitTimer - - -class NoRetiming(Special): - def __init__(self, reg): - Special.__init__(self) - self.reg = reg - - # do nothing - @staticmethod - def lower(dr): - return Module() - - -class MultiRegImpl(Module): - def __init__(self, i, o, odomain, n): - self.i = i - self.o = o - self.odomain = odomain - - w, signed = value_bits_sign(self.i) - self.regs = [Signal((w, signed)) for i in range(n)] - - ### - - src = self.i - for reg in self.regs: - sd = getattr(self.sync, self.odomain) - sd += reg.eq(src) - src = reg - self.comb += self.o.eq(src) - self.specials += [NoRetiming(reg) for reg in self.regs] - - -class MultiReg(Special): - def __init__(self, i, o, odomain="sys", n=2): - Special.__init__(self) - self.i = wrap(i) - self.o = wrap(o) - self.odomain = odomain - self.n = n - - def iter_expressions(self): - yield self, "i", SPECIAL_INPUT - yield self, "o", SPECIAL_OUTPUT - - def rename_clock_domain(self, old, new): - Special.rename_clock_domain(self, old, new) - if self.odomain == old: - self.odomain = new - - def list_clock_domains(self): - r = Special.list_clock_domains(self) - r.add(self.odomain) - return r - - @staticmethod - def lower(dr): - return MultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) - - -class PulseSynchronizer(Module): - def __init__(self, idomain, odomain): - self.i = Signal() - self.o = Signal() - - ### - - toggle_i = Signal() - toggle_o = Signal() - toggle_o_r = Signal() - - sync_i = getattr(self.sync, idomain) - sync_o = getattr(self.sync, odomain) - - sync_i += If(self.i, toggle_i.eq(~toggle_i)) - self.specials += MultiReg(toggle_i, toggle_o, odomain) - sync_o += toggle_o_r.eq(toggle_o) - self.comb += self.o.eq(toggle_o ^ toggle_o_r) - - -class BusSynchronizer(Module): - """Clock domain transfer of several bits at once. - - Ensures that all the bits form a single word that was present - synchronously in the input clock domain (unlike direct use of - ``MultiReg``).""" - def __init__(self, width, idomain, odomain, timeout=128): - self.i = Signal(width) - self.o = Signal(width) - - if width == 1: - self.specials += MultiReg(self.i, self.o, odomain) - else: - sync_i = getattr(self.sync, idomain) - sync_o = getattr(self.sync, odomain) - - starter = Signal(reset=1) - sync_i += starter.eq(0) - self.submodules._ping = PulseSynchronizer(idomain, odomain) - self.submodules._pong = PulseSynchronizer(odomain, idomain) - self.submodules._timeout = WaitTimer(timeout) - self.comb += [ - self._timeout.wait.eq(~self._ping.i), - self._ping.i.eq(starter | self._pong.o | self._timeout.done), - self._pong.i.eq(self._ping.i) - ] - - ibuffer = Signal(width) - obuffer = Signal(width) - sync_i += If(self._pong.o, ibuffer.eq(self.i)) - self.specials += MultiReg(ibuffer, obuffer, odomain) - sync_o += If(self._ping.o, self.o.eq(obuffer)) - - -class GrayCounter(Module): - def __init__(self, width): - self.ce = Signal() - self.q = Signal(width) - self.q_next = Signal(width) - self.q_binary = Signal(width) - self.q_next_binary = Signal(width) - - ### - - self.comb += [ - If(self.ce, - self.q_next_binary.eq(self.q_binary + 1) - ).Else( - self.q_next_binary.eq(self.q_binary) - ), - self.q_next.eq(self.q_next_binary ^ self.q_next_binary[1:]) - ] - self.sync += [ - self.q_binary.eq(self.q_next_binary), - self.q.eq(self.q_next) - ] diff --git a/litex/gen/migen/genlib/divider.py b/litex/gen/migen/genlib/divider.py deleted file mode 100644 index f31c7407..00000000 --- a/litex/gen/migen/genlib/divider.py +++ /dev/null @@ -1,40 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module - - -class Divider(Module): - def __init__(self, w): - self.start_i = Signal() - self.dividend_i = Signal(w) - self.divisor_i = Signal(w) - self.ready_o = Signal() - self.quotient_o = Signal(w) - self.remainder_o = Signal(w) - - ### - - qr = Signal(2*w) - counter = Signal(max=w+1) - divisor_r = Signal(w) - diff = Signal(w+1) - - self.comb += [ - self.quotient_o.eq(qr[:w]), - self.remainder_o.eq(qr[w:]), - self.ready_o.eq(counter == 0), - diff.eq(qr[w-1:] - divisor_r) - ] - self.sync += [ - If(self.start_i, - counter.eq(w), - qr.eq(self.dividend_i), - divisor_r.eq(self.divisor_i) - ).Elif(~self.ready_o, - If(diff[w], - qr.eq(Cat(0, qr[:2*w-1])) - ).Else( - qr.eq(Cat(1, qr[:w-1], diff[:w])) - ), - counter.eq(counter - 1) - ) - ] diff --git a/litex/gen/migen/genlib/fifo.py b/litex/gen/migen/genlib/fifo.py deleted file mode 100644 index 8f4e1423..00000000 --- a/litex/gen/migen/genlib/fifo.py +++ /dev/null @@ -1,214 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.specials import Memory -from migen.fhdl.bitcontainer import log2_int -from migen.fhdl.decorators import ClockDomainsRenamer -from migen.genlib.cdc import NoRetiming, MultiReg, GrayCounter - - -def _inc(signal, modulo): - if modulo == 2**len(signal): - return signal.eq(signal + 1) - else: - return If(signal == (modulo - 1), - signal.eq(0) - ).Else( - signal.eq(signal + 1) - ) - - -class _FIFOInterface: - """ - Data written to the input interface (`din`, `we`, `writable`) is - buffered and can be read at the output interface (`dout`, `re`, - `readable`). The data entry written first to the input - also appears first on the output. - - Parameters - ---------- - width : int - Bit width for the data. - depth : int - Depth of the FIFO. - - Attributes - ---------- - din : in, width - Input data - writable : out - There is space in the FIFO and `we` can be asserted to load new data. - we : in - Write enable signal to latch `din` into the FIFO. Does nothing if - `writable` is not asserted. - dout : out, width - Output data. Only valid if `readable` is asserted. - readable : out - Output data `dout` valid, FIFO not empty. - re : in - Acknowledge `dout`. If asserted, the next entry will be - available on the next cycle (if `readable` is high then). - """ - def __init__(self, width, depth): - self.we = Signal() - self.writable = Signal() # not full - self.re = Signal() - self.readable = Signal() # not empty - - self.din = Signal(width) - self.dout = Signal(width) - self.width = width - - -class SyncFIFO(Module, _FIFOInterface): - """Synchronous FIFO (first in, first out) - - Read and write interfaces are accessed from the same clock domain. - If different clock domains are needed, use :class:`AsyncFIFO`. - - {interface} - level : out - Number of unread entries. - replace : in - Replaces the last entry written into the FIFO with `din`. Does nothing - if that entry has already been read (i.e. the FIFO is empty). - Assert in conjunction with `we`. - """ - __doc__ = __doc__.format(interface=_FIFOInterface.__doc__) - - def __init__(self, width, depth, fwft=True): - _FIFOInterface.__init__(self, width, depth) - - self.level = Signal(max=depth+1) - self.replace = Signal() - - ### - - produce = Signal(max=depth) - consume = Signal(max=depth) - storage = Memory(self.width, depth) - self.specials += storage - - wrport = storage.get_port(write_capable=True) - self.specials += wrport - self.comb += [ - If(self.replace, - wrport.adr.eq(produce-1) - ).Else( - wrport.adr.eq(produce) - ), - wrport.dat_w.eq(self.din), - wrport.we.eq(self.we & (self.writable | self.replace)) - ] - self.sync += If(self.we & self.writable & ~self.replace, - _inc(produce, depth)) - - do_read = Signal() - self.comb += do_read.eq(self.readable & self.re) - - rdport = storage.get_port(async_read=fwft, has_re=not fwft) - self.specials += rdport - self.comb += [ - rdport.adr.eq(consume), - self.dout.eq(rdport.dat_r) - ] - if not fwft: - self.comb += rdport.re.eq(do_read) - self.sync += If(do_read, _inc(consume, depth)) - - self.sync += \ - If(self.we & self.writable & ~self.replace, - If(~do_read, self.level.eq(self.level + 1)) - ).Elif(do_read, - self.level.eq(self.level - 1) - ) - self.comb += [ - self.writable.eq(self.level != depth), - self.readable.eq(self.level != 0) - ] - - -class SyncFIFOBuffered(Module, _FIFOInterface): - def __init__(self, width, depth): - _FIFOInterface.__init__(self, width, depth) - self.submodules.fifo = fifo = SyncFIFO(width, depth, False) - - self.writable = fifo.writable - self.din = fifo.din - self.we = fifo.we - self.dout = fifo.dout - self.level = Signal(max=depth+2) - - ### - - self.comb += fifo.re.eq(fifo.readable & (~self.readable | self.re)) - self.sync += \ - If(fifo.re, - self.readable.eq(1), - ).Elif(self.re, - self.readable.eq(0), - ) - self.comb += self.level.eq(fifo.level + self.readable) - - -class AsyncFIFO(Module, _FIFOInterface): - """Asynchronous FIFO (first in, first out) - - Read and write interfaces are accessed from different clock domains, - named `read` and `write`. Use `ClockDomainsRenamer` to rename to - other names. - - {interface} - """ - __doc__ = __doc__.format(interface=_FIFOInterface.__doc__) - - def __init__(self, width, depth): - _FIFOInterface.__init__(self, width, depth) - - ### - - depth_bits = log2_int(depth, True) - - produce = ClockDomainsRenamer("write")(GrayCounter(depth_bits+1)) - consume = ClockDomainsRenamer("read")(GrayCounter(depth_bits+1)) - self.submodules += produce, consume - self.comb += [ - produce.ce.eq(self.writable & self.we), - consume.ce.eq(self.readable & self.re) - ] - - produce_rdomain = Signal(depth_bits+1) - self.specials += [ - NoRetiming(produce.q), - MultiReg(produce.q, produce_rdomain, "read") - ] - consume_wdomain = Signal(depth_bits+1) - self.specials += [ - NoRetiming(consume.q), - MultiReg(consume.q, consume_wdomain, "write") - ] - if depth_bits == 1: - self.comb += self.writable.eq((produce.q[-1] == consume_wdomain[-1]) - | (produce.q[-2] == consume_wdomain[-2])) - else: - self.comb += [ - self.writable.eq((produce.q[-1] == consume_wdomain[-1]) - | (produce.q[-2] == consume_wdomain[-2]) - | (produce.q[:-2] != consume_wdomain[:-2])) - ] - self.comb += self.readable.eq(consume.q != produce_rdomain) - - storage = Memory(self.width, depth) - self.specials += storage - wrport = storage.get_port(write_capable=True, clock_domain="write") - self.specials += wrport - self.comb += [ - wrport.adr.eq(produce.q_binary[:-1]), - wrport.dat_w.eq(self.din), - wrport.we.eq(produce.ce) - ] - rdport = storage.get_port(clock_domain="read") - self.specials += rdport - self.comb += [ - rdport.adr.eq(consume.q_next_binary[:-1]), - self.dout.eq(rdport.dat_r) - ] diff --git a/litex/gen/migen/genlib/misc.py b/litex/gen/migen/genlib/misc.py deleted file mode 100644 index f8f4a7c4..00000000 --- a/litex/gen/migen/genlib/misc.py +++ /dev/null @@ -1,88 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.bitcontainer import bits_for - - -def split(v, *counts): - r = [] - offset = 0 - for n in counts: - if n != 0: - r.append(v[offset:offset+n]) - else: - r.append(None) - offset += n - return tuple(r) - - -def displacer(signal, shift, output, n=None, reverse=False): - if shift is None: - return output.eq(signal) - if n is None: - n = 2**len(shift) - w = len(signal) - if reverse: - r = reversed(range(n)) - else: - r = range(n) - l = [Replicate(shift == i, w) & signal for i in r] - return output.eq(Cat(*l)) - - -def chooser(signal, shift, output, n=None, reverse=False): - if shift is None: - return output.eq(signal) - if n is None: - n = 2**len(shift) - w = len(output) - cases = {} - for i in range(n): - if reverse: - s = n - i - 1 - else: - s = i - cases[i] = [output.eq(signal[s*w:(s+1)*w])] - return Case(shift, cases).makedefault() - - -def timeline(trigger, events): - lastevent = max([e[0] for e in events]) - counter = Signal(max=lastevent+1) - - counterlogic = If(counter != 0, - counter.eq(counter + 1) - ).Elif(trigger, - counter.eq(1) - ) - # insert counter reset if it doesn't naturally overflow - # (test if lastevent+1 is a power of 2) - if (lastevent & (lastevent + 1)) != 0: - counterlogic = If(counter == lastevent, - counter.eq(0) - ).Else( - counterlogic - ) - - def get_cond(e): - if e[0] == 0: - return trigger & (counter == 0) - else: - return counter == e[0] - sync = [If(get_cond(e), *e[1]) for e in events] - sync.append(counterlogic) - return sync - - -class WaitTimer(Module): - def __init__(self, t): - self.wait = Signal() - self.done = Signal() - - # # # - - count = Signal(bits_for(t), reset=t) - self.comb += self.done.eq(count == 0) - self.sync += \ - If(self.wait, - If(~self.done, count.eq(count - 1)) - ).Else(count.eq(count.reset)) diff --git a/litex/gen/migen/genlib/sort.py b/litex/gen/migen/genlib/sort.py deleted file mode 100644 index 8f38e629..00000000 --- a/litex/gen/migen/genlib/sort.py +++ /dev/null @@ -1,71 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module - - -class BitonicSort(Module): - """Combinatorial sorting network - - The Bitonic sort is implemented as a combinatorial sort using - comparators and multiplexers. Its asymptotic complexity (in terms of - number of comparators/muxes) is O(n log(n)**2), like mergesort or - shellsort. - - http://www.dps.uibk.ac.at/~cosenza/teaching/gpu/sort-batcher.pdf - - http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/bitonicen.htm - - http://www.myhdl.org/doku.php/cookbook:bitonic - - Parameters - ---------- - n : int - Number of inputs and output signals. - m : int - Bit width of inputs and outputs. Or a tuple of `(m, signed)`. - ascending : bool - Sort direction. `True` if input is to be sorted ascending, - `False` for descending. Defaults to ascending. - - Attributes - ---------- - i : list of Signals, in - Input values, each `m` wide. - o : list of Signals, out - Output values, sorted, each `m` bits wide. - """ - def __init__(self, n, m, ascending=True): - self.i = [Signal(m) for i in range(n)] - self.o = [Signal(m) for i in range(n)] - self._sort(self.i, self.o, int(ascending), m) - - def _sort_two(self, i0, i1, o0, o1, dir): - self.comb += [ - o0.eq(i0), - o1.eq(i1), - If(dir == (i0 > i1), - o0.eq(i1), - o1.eq(i0), - )] - - def _merge(self, i, o, dir, m): - n = len(i) - k = n//2 - if n > 1: - t = [Signal(m) for j in range(n)] - for j in range(k): - self._sort_two(i[j], i[j + k], t[j], t[j + k], dir) - self._merge(t[:k], o[:k], dir, m) - self._merge(t[k:], o[k:], dir, m) - else: - self.comb += o[0].eq(i[0]) - - def _sort(self, i, o, dir, m): - n = len(i) - k = n//2 - if n > 1: - t = [Signal(m) for j in range(n)] - self._sort(i[:k], t[:k], 1, m) # ascending - self._sort(i[k:], t[k:], 0, m) # descending - self._merge(t, o, dir, m) - else: - self.comb += o[0].eq(i[0]) diff --git a/litex/gen/migen/sim/__init__.py b/litex/gen/migen/sim/__init__.py deleted file mode 100644 index d99780b8..00000000 --- a/litex/gen/migen/sim/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from migen.sim.core import Simulator, run_simulation diff --git a/litex/gen/migen/sim/vcd.py b/litex/gen/migen/sim/vcd.py deleted file mode 100644 index f3ea7aee..00000000 --- a/litex/gen/migen/sim/vcd.py +++ /dev/null @@ -1,75 +0,0 @@ -from itertools import count - -from migen.fhdl.namer import build_namespace - - -def vcd_codes(): - codechars = [chr(i) for i in range(33, 127)] - for n in count(): - q, r = divmod(n, len(codechars)) - code = codechars[r] - while q > 0: - q, r = divmod(q, len(codechars)) - code = codechars[r] + code - yield code - - -class VCDWriter: - def __init__(self, filename, signals): - self.fo = open(filename, "w") - self.codes = dict() - self.signal_values = dict() - self.t = 0 - - try: - ns = build_namespace(signals) - codes = vcd_codes() - for signal in signals: - name = ns.get_name(signal) - code = next(codes) - self.codes[signal] = code - self.fo.write("$var wire {len} {code} {name} $end\n" - .format(name=name, code=code, len=len(signal))) - self.fo.write("$dumpvars\n") - for signal in signals: - value = signal.reset.value - self._write_value(signal, value) - self.signal_values[signal] = value - self.fo.write("$end\n") - self.fo.write("#0\n") - except: - self.close() - raise - - def _write_value(self, signal, value): - l = len(signal) - if value < 0: - value += 2**l - if l > 1: - fmtstr = "b{:0" + str(l) + "b} {}\n" - else: - fmtstr = "{}{}\n" - self.fo.write(fmtstr.format(value, self.codes[signal])) - - def set(self, signal, value): - if self.signal_values[signal] != value: - self._write_value(signal, value) - self.signal_values[signal] = value - - def delay(self, delay): - self.t += delay - self.fo.write("#{}\n".format(self.t)) - - def close(self): - self.fo.close() - - -class DummyVCDWriter: - def set(self, signal, value): - pass - - def delay(self, delay): - pass - - def close(self): - pass diff --git a/litex/gen/migen/test/support.py b/litex/gen/migen/test/support.py deleted file mode 100644 index c1bb4697..00000000 --- a/litex/gen/migen/test/support.py +++ /dev/null @@ -1,13 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class SimCase: - def setUp(self, *args, **kwargs): - self.tb = self.TestBench(*args, **kwargs) - - def test_to_verilog(self): - verilog.convert(self.tb) - - def run_with(self, generator): - run_simulation(self.tb, generator) diff --git a/litex/gen/migen/test/test_coding.py b/litex/gen/migen/test/test_coding.py deleted file mode 100644 index 64cfb6fd..00000000 --- a/litex/gen/migen/test/test_coding.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest - -from migen import * -from migen.genlib.coding import * - -from migen.test.support import SimCase - - -class EncCase(SimCase, unittest.TestCase): - class TestBench(Module): - def __init__(self): - self.submodules.dut = Encoder(8) - - def test_sizes(self): - self.assertEqual(len(self.tb.dut.i), 8) - self.assertEqual(len(self.tb.dut.o), 3) - self.assertEqual(len(self.tb.dut.n), 1) - - def test_run_sequence(self): - seq = list(range(1<<8)) - def gen(): - for _ in range(256): - if seq: - yield self.tb.dut.i.eq(seq.pop(0)) - if (yield self.tb.dut.n): - self.assertNotIn((yield self.tb.dut.i), [1< 0: - self.assertEqual(i & 1<<(o - 1), 0) - self.assertGreaterEqual(i, 1< 0: - self.assertEqual(i & 1<<(o - 1), 0) - self.assertGreaterEqual(i, 1< q, - lambda p, q: p >= q, - lambda p, q: p < q, - lambda p, q: p <= q, - lambda p, q: p == q, - lambda p, q: p != q, - ] - self.vals = [] - for asign in 1, -1: - for bsign in 1, -1: - for f in comps: - r = Signal() - r0 = f(asign*self.a, bsign*self.b) - self.comb += r.eq(r0) - self.vals.append((asign, bsign, f, r, r0.op)) - - def test_comparisons(self): - def gen(): - for i in range(-4, 4): - yield self.tb.a.eq(i) - yield self.tb.b.eq(i) - a = yield self.tb.a - b = yield self.tb.b - for asign, bsign, f, r, op in self.tb.vals: - r, r0 = (yield r), f(asign*a, bsign*b) - self.assertEqual(r, int(r0), - "got {}, want {}*{} {} {}*{} = {}".format( - r, asign, a, op, bsign, b, r0)) - yield - self.run_with(gen()) diff --git a/litex/gen/migen/test/test_size.py b/litex/gen/migen/test/test_size.py deleted file mode 100644 index a44ae367..00000000 --- a/litex/gen/migen/test/test_size.py +++ /dev/null @@ -1,19 +0,0 @@ -import unittest - -from migen import * - - -def _same_slices(a, b): - return a.value is b.value and a.start == b.start and a.stop == b.stop - - -class SignalSizeCase(unittest.TestCase): - def setUp(self): - self.i = C(0xaa) - self.j = C(-127) - self.s = Signal((13, True)) - - def test_len(self): - self.assertEqual(len(self.s), 13) - self.assertEqual(len(self.i), 8) - self.assertEqual(len(self.j), 8) diff --git a/litex/gen/migen/test/test_sort.py b/litex/gen/migen/test/test_sort.py deleted file mode 100644 index acb9fa23..00000000 --- a/litex/gen/migen/test/test_sort.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest -from random import randrange - -from migen import * -from migen.genlib.sort import * - -from migen.test.support import SimCase - - -class BitonicCase(SimCase, unittest.TestCase): - class TestBench(Module): - def __init__(self): - self.submodules.dut = BitonicSort(8, 4, ascending=True) - - def test_sizes(self): - self.assertEqual(len(self.tb.dut.i), 8) - self.assertEqual(len(self.tb.dut.o), 8) - for i in range(8): - self.assertEqual(len(self.tb.dut.i[i]), 4) - self.assertEqual(len(self.tb.dut.o[i]), 4) - - def test_sort(self): - def gen(): - for repeat in range(20): - for i in self.tb.dut.i: - yield i.eq(randrange(1< 2014,2015 - -# assuming your xilinx toolchain lives in /opt/Xilinx, -# run `strace_tailor.sh /opt/Xilinx/ [synthesis script] [options]`, -# e.g. for the pipistrello target of misoc: -# strace_tailor.sh /opt/Xilinx/ ./make.py -t pipistrello build-bitstream -# then in your current directory, `opt/Xilinx/*` is the -# minimal toolchain required for this synthesis script run. - -PREFIX=$1 -shift -strace -e trace=file,process -f -o strace.log $@ -sed -n 's|^.*"\('"$PREFIX"'[^"]*\)".*$|\1|p' strace.log \ - | sort | uniq | xargs -d '\n' \ - cp --parent --no-dereference --preserve=all -t . diff --git a/litex/soc/misoc/cores/__init__.py b/litex/gen/util/__init__.py similarity index 100% rename from litex/soc/misoc/cores/__init__.py rename to litex/gen/util/__init__.py diff --git a/litex/gen/migen/util/misc.py b/litex/gen/util/misc.py similarity index 100% rename from litex/gen/migen/util/misc.py rename to litex/gen/util/misc.py diff --git a/litex/soc/.gitignore b/litex/soc/.gitignore deleted file mode 100644 index 9e102e66..00000000 --- a/litex/soc/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -__pycache__ -*.pyc -*.egg-info -*.vcd -outgoing diff --git a/litex/soc/.gitmodules b/litex/soc/.gitmodules deleted file mode 100644 index 1651ece3..00000000 --- a/litex/soc/.gitmodules +++ /dev/null @@ -1,12 +0,0 @@ -[submodule "misoc/cores/lm32/verilog/submodule"] - path = misoc/cores/lm32/verilog/submodule - url = https://github.com/m-labs/lm32.git -[submodule "misoc/cores/mor1kx/verilog"] - path = misoc/cores/mor1kx/verilog - url = https://github.com/openrisc/mor1kx.git -[submodule "misoc/software/compiler_rt"] - path = misoc/software/compiler_rt - url = http://llvm.org/git/compiler-rt.git -[submodule "misoc/software/unwinder"] - path = misoc/software/unwinder - url = https://github.com/whitequark/libunwind diff --git a/litex/soc/.travis.yml b/litex/soc/.travis.yml deleted file mode 100644 index 4b094bc0..00000000 --- a/litex/soc/.travis.yml +++ /dev/null @@ -1,36 +0,0 @@ -language: python -python: - - "3.5" - -env: - global: - - PATH=$HOME/miniconda/bin:$PATH - -before_install: - # Install Miniconda - - wget https://raw.githubusercontent.com/m-labs/artiq/master/.travis/get-anaconda.sh - - chmod +x get-anaconda.sh - - ./get-anaconda.sh - - source $HOME/miniconda/bin/activate py35 - - conda install anaconda-client -install: - # workaround for https://github.com/conda/conda-build/issues/466 - - "mkdir -p /home/travis/miniconda/conda-bld/linux-64" - - "conda index /home/travis/miniconda/conda-bld/linux-64" - - "conda build --python 3.5 conda/misoc" - - "conda install $(conda build --output --python 3.5 conda/misoc)" -script: - - true - -after_success: - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda login --hostname $(hostname) --username $binstar_login --password $binstar_password; fi - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then anaconda upload --user $binstar_login --channel dev --force $HOME/miniconda/conda-bld/noarch/misoc-*.tar.bz2; fi - -notifications: - email: false - irc: - channels: - - chat.freenode.net#m-labs - template: - - "%{repository}#%{build_number} (%{branch} - %{commit} : %{author}): %{message}" - - "Build details : %{build_url}" diff --git a/litex/soc/CONTRIBUTING.rst b/litex/soc/CONTRIBUTING.rst deleted file mode 100644 index 72bbdfa7..00000000 --- a/litex/soc/CONTRIBUTING.rst +++ /dev/null @@ -1,68 +0,0 @@ - -# Sending Patches - -MiSoC does **not** use GitHub pull requests. Instead you must send patches to -the public mailing list . - -Before sending patches, please read the rest of this guide and make sure your -patch meets the following criteria; - - - [ ] Meets style guide requirements listed below. - - [ ] Includes a suitable commit message. - -Sending mail to the mailing list can be done via the `git send-email` tool. -The `git send-email` tool is not included by default on many Linux -distributions, on Ubuntu / Debian systems you may need to install the -`git-email` package. Documentation on using this tool can be found at -http://git-scm.com/docs/git-send-email - -To send patches to the mailing list you must first be subscribed to the list. -You can subscribe at https://ssl.serverraum.org/lists/listinfo/devel - -An example session would be; -``` -# Set up [sendemail] as described at http://git-scm.com/docs/git-send-email in -# the EXAMPLE section. - -# Download, make changes to misoc and commit them -git clone https://github.com/m-labs/misoc -cd misoc -edit xxx.py -git commit -a - -# Send patch to mailing list -# -------------------------- -# 1) Remove any previous outgoing patch -rm -rf outgoing - -# 2) Put the patches to be sent into the outgoing directory -git format-patch --cover-letter -M origin/master -o outgoing/ - -# 3) Edit the cover letter with information about the patch -edit outgoing/0000-* - -# 4) Actually send the email. -git send-email --to=devel@lists.m-labs.hk outgoing/* -``` - -# Help - -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 (#m-labs on Freenode) -beforehand. - -# Style Guide - -All code should be compliant with the -[PEP8 style guide](https://www.python.org/dev/peps/pep-0008/). - -You can use the [pep8 tool](https://www.python.org/dev/peps/pep-0008/) to check -compliance with `pep8 myfile.py` - -When modifying existing code **be consistent** with any existing code style. - -# License - -All new contributions should be under the same license as MiSoC. This is a very -permissive two-clause BSD license. Full license text can be found at -https://github.com/m-labs/misoc/blob/master/LICENSE diff --git a/litex/soc/MANIFEST.in b/litex/soc/MANIFEST.in deleted file mode 100644 index 39d97e61..00000000 --- a/litex/soc/MANIFEST.in +++ /dev/null @@ -1,4 +0,0 @@ -graft misoc/software -graft misoc/cores/lm32/verilog -graft misoc/cores/mor1kx/verilog -include misoc/cores/mxcrg.v diff --git a/litex/soc/LICENSE b/litex/soc/MISOC_LICENSE similarity index 100% rename from litex/soc/LICENSE rename to litex/soc/MISOC_LICENSE diff --git a/litex/soc/README b/litex/soc/README deleted file mode 100644 index 468fbef6..00000000 --- a/litex/soc/README +++ /dev/null @@ -1,138 +0,0 @@ - __ ___ _ ____ _____ - / |/ / (_) / __/__ / ___/ - / /|_/ / / / _\ \/ _ \/ /__ - /_/ /_/ /_/ /___/\___/\___/ - - Copyright 2007-2015 / M-Labs Ltd - Copyright 2012-2015 / Enjoy-Digital - - a high performance and small footprint SoC based on Migen - -[> Features ------------ - * LatticeMico32 CPU, modified to include an optional MMU (experimental). - * mor1kx (a better OpenRISC implementation) as alternative CPU option. - * High performance memory controller capable of issuing several SDRAM commands - per FPGA cycle. - * Supports SDR, DDR, LPDDR, DDR2 and DDR3. - * Provided peripherals: UART, GPIO, timer, GPIO, NOR flash controller, SPI - flash controller, Ethernet MAC, and more. - * High performance: - - on Spartan-6, 83MHz system clock frequencies, 10+Gbps DDR - SDRAM bandwidth, 1080p 32bpp framebuffer, etc. - - on Kintex-7, 125MHz system clock frequencies (up to 200MHz without DDR3), - 64Gbps DDR3 SDRAM bandwidth. - * Low resource usage: basic implementation fits easily in Spartan-6 LX9. - * Portable and easy to customize thanks to Python- and Migen-based - architecture. - * Design new peripherals using Migen and benefit from automatic CSR maps - and logic, etc. - * Possibility to encapsulate legacy Verilog/VHDL code. - * Complex FPGA cores that can be used integrated in MiSoC or standalone: - - LiteEth: a small footprint and configurable Ethernet core - -MiSoC comes with built-in support for the following boards: - * Mixxeo, the digital video mixer from M-Labs [XC6SLX45] - * Milkymist One, the original M-Labs video synthesizer [XC6SLX45] - * Papilio Pro, a simple and low-cost development board [XC6SLX9] - * Pipistrello, a simple board with USB and HDMI [XC6SLX45] - * De0 Nano, a simple and low-cost development board [CYCLONEIV] - * KC705, a Kintex-7 devboard from Xilinx [XC7K325T] - * Versa, a low-cost Lattice development board [ECP3-35] -MiSoC is portable and support for other boards can easily be added as external -modules. - -[> Quick start guide --------------------- -0. If cloned from Git without the --recursive option, get the submodules: - git submodule update --init - -1. Install Python 3.3+, Migen and FPGA vendor's development tools. - Get Migen from: https://github.com/m-labs/migen - -2. Install JTAG tools. - For Mixxeo and M1: http://urjtag.org - For Papilio Pro and KC705: http://xc3sprog.sourceforge.net - For De0 Nano: USBBlaster from Altera - We recommend using xc3sprog for Xilinx devices, but Vivado programmer - is also supported for Xilinx 7-series. - -3. (Optional, only needed if you want to flash the bistream/software) - Obtain and build any required flash proxy bitstreams. Flash proxy bitstreams - give JTAG access to a flash chip through the FPGA. - For Mixxeo and M1: https://github.com/m-labs/fjmem-m1 - For Papilio Pro: https://github.com/GadgetFactory/Papilio-Loader - (xc3sprog/trunk/bscan_spi/bscan_spi_lx9_papilio.bit) - For KC705: https://github.com/m-labs/bscan_spi_kc705 - -4. Compile and install binutils. Take the latest version from GNU. - mkdir build && cd build - ../configure --target=lm32-elf - make - make install - -5. Compile and install GCC. Take gcc-core and gcc-g++ from GNU - (version 4.5 or >=4.9). - rm -rf libstdc++-v3 - mkdir build && cd build - ../configure --target=lm32-elf --enable-languages="c,c++" --disable-libgcc \ - --disable-libssp - make - make install - -6. Build and flash the BIOS and bitstream. Run from MiSoC: - For Mixxeo: ./make.py all - For M1: ./make.py -p m1 all - For Papilio Pro: ./make.py -t ppro all - For Pipistrello: ./make.py -t pipistrello all - For De0 Nano: ./make.py -t de0nano all load-bitstream - For KC705: ./make.py -t kc705 all - - If just want to load the bitstream in volatile SRAM use: - all load-bitstream - -7. Run a terminal program on the board's serial port at 115200 8-N-1. - You should get the BIOS prompt. - -8. Read and experiment with the source! - Come to our IRC channel and mailing list! - A simple target is provided to test MiSoC easily with your board: - Create your target with a clock and serial pins. - Build and test it: ./make.py -t simple -p your_platform all load-bitstream - If you don't have access to a FPGA board, you can also try MiSoC - with Verilator: - Download and install Verilator: http://www.veripool.org/ - Test it: ./make.py -t simple -p sim build-bitstream - -9. Contribute a patch! - Once you have experimented with stuff, please send your results back. - For more details on how to do so, you can see the CONTRIBUTING.rst file. - -[> License ----------- -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 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 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 (#m-labs on Freenode) beforehand. - -See LICENSE file for full copyright and license info. - -[> Links --------- -Web: - http://m-labs.hk - http://enjoy-digital.fr - -Code repository: - https://github.com/m-labs/misoc - -You can contact us on the public mailing list devel [AT] lists.m-labs.hk. diff --git a/litex/soc/misoc/cores/liteeth_mini/__init__.py b/litex/soc/__init__.py similarity index 100% rename from litex/soc/misoc/cores/liteeth_mini/__init__.py rename to litex/soc/__init__.py diff --git a/litex/soc/conda/misoc/bld.bat b/litex/soc/conda/misoc/bld.bat deleted file mode 100644 index 39b5e1fe..00000000 --- a/litex/soc/conda/misoc/bld.bat +++ /dev/null @@ -1 +0,0 @@ -%PYTHON% setup.py install diff --git a/litex/soc/conda/misoc/meta.yaml b/litex/soc/conda/misoc/meta.yaml deleted file mode 100644 index a2714f35..00000000 --- a/litex/soc/conda/misoc/meta.yaml +++ /dev/null @@ -1,26 +0,0 @@ -package: - name: misoc - version: {{ environ.get("GIT_DESCRIBE_TAG", "") }} - -source: - git_url: https://github.com/m-labs/misoc - git_tag: master - -build: - noarch_python: true - number: {{ environ.get("GIT_DESCRIBE_NUMBER", 0) }} - string: py_{{ environ.get("GIT_DESCRIBE_NUMBER", 0) }}+git{{ environ.get("GIT_DESCRIBE_HASH", "")[1:] }} - script: $PYTHON setup.py install - -requirements: - build: - - migen - - python - run: - - migen - - python - -about: - home: http://m-labs.hk/gateware.html - license: 3-clause BSD - summary: 'A high performance and small footprint SoC based on Migen' diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/frontend/__init__.py b/litex/soc/cores/__init__.py similarity index 100% rename from litex/soc/misoc/cores/liteeth_mini/mac/frontend/__init__.py rename to litex/soc/cores/__init__.py diff --git a/litex/soc/misoc/interconnect/__init__.py b/litex/soc/cores/cpu/__init__.py similarity index 100% rename from litex/soc/misoc/interconnect/__init__.py rename to litex/soc/cores/cpu/__init__.py diff --git a/litex/soc/cores/cpu/lm32/__init__.py b/litex/soc/cores/cpu/lm32/__init__.py new file mode 100644 index 00000000..c103b84b --- /dev/null +++ b/litex/soc/cores/cpu/lm32/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.lm32.core import LM32 diff --git a/litex/soc/misoc/cores/lm32/core.py b/litex/soc/cores/cpu/lm32/core.py similarity index 97% rename from litex/soc/misoc/cores/lm32/core.py rename to litex/soc/cores/cpu/lm32/core.py index fd1b1e95..7d590c84 100644 --- a/litex/soc/misoc/cores/lm32/core.py +++ b/litex/soc/cores/cpu/lm32/core.py @@ -1,8 +1,8 @@ import os -from migen import * +from litex.gen import * -from misoc.interconnect import wishbone +from litex.soc.interconnect import wishbone class LM32(Module): diff --git a/litex/soc/misoc/cores/lm32/verilog/lm32_config.v b/litex/soc/cores/cpu/lm32/verilog/lm32_config.v similarity index 100% rename from litex/soc/misoc/cores/lm32/verilog/lm32_config.v rename to litex/soc/cores/cpu/lm32/verilog/lm32_config.v diff --git a/litex/soc/cores/cpu/lm32/verilog/submodule b/litex/soc/cores/cpu/lm32/verilog/submodule new file mode 160000 index 00000000..84b3e3ca --- /dev/null +++ b/litex/soc/cores/cpu/lm32/verilog/submodule @@ -0,0 +1 @@ +Subproject commit 84b3e3ca0ad9535acaef201c1482342871358b08 diff --git a/litex/soc/cores/cpu/mor1kx/__init__.py b/litex/soc/cores/cpu/mor1kx/__init__.py new file mode 100644 index 00000000..1f7c15eb --- /dev/null +++ b/litex/soc/cores/cpu/mor1kx/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.cpu.mor1kx.core import MOR1KX diff --git a/litex/soc/misoc/cores/mor1kx/core.py b/litex/soc/cores/cpu/mor1kx/core.py similarity index 98% rename from litex/soc/misoc/cores/mor1kx/core.py rename to litex/soc/cores/cpu/mor1kx/core.py index a4b5e0d0..8511fff5 100644 --- a/litex/soc/misoc/cores/mor1kx/core.py +++ b/litex/soc/cores/cpu/mor1kx/core.py @@ -1,8 +1,8 @@ import os -from migen import * +from litex.gen import * -from misoc.interconnect import wishbone +from litex.soc.interconnect import wishbone class MOR1KX(Module): diff --git a/litex/soc/cores/cpu/mor1kx/verilog b/litex/soc/cores/cpu/mor1kx/verilog new file mode 160000 index 00000000..69b97fcb --- /dev/null +++ b/litex/soc/cores/cpu/mor1kx/verilog @@ -0,0 +1 @@ +Subproject commit 69b97fcb43b35d6c6639ecc68e63d912c09ee8da diff --git a/litex/soc/misoc/targets/__init__.py b/litex/soc/cores/flash/__init__.py similarity index 100% rename from litex/soc/misoc/targets/__init__.py rename to litex/soc/cores/flash/__init__.py diff --git a/litex/soc/misoc/cores/nor_flash_16.py b/litex/soc/cores/flash/nor_flash_16.py similarity index 96% rename from litex/soc/misoc/cores/nor_flash_16.py rename to litex/soc/cores/flash/nor_flash_16.py index 9761b576..3027882a 100644 --- a/litex/soc/misoc/cores/nor_flash_16.py +++ b/litex/soc/cores/flash/nor_flash_16.py @@ -1,7 +1,7 @@ -from migen import * -from migen.genlib.fsm import FSM, NextState +from litex.gen import * +from litex.gen.genlib.fsm import FSM, NextState -from misoc.interconnect import wishbone +from litex.soc.interconnect import wishbone class NorFlash16(Module): diff --git a/litex/soc/misoc/cores/spi_flash.py b/litex/soc/cores/flash/spi_flash.py similarity index 95% rename from litex/soc/misoc/cores/spi_flash.py rename to litex/soc/cores/flash/spi_flash.py index fca8c6c6..69b86004 100644 --- a/litex/soc/misoc/cores/spi_flash.py +++ b/litex/soc/cores/flash/spi_flash.py @@ -1,8 +1,8 @@ -from migen import * -from migen.genlib.misc import timeline +from litex.gen import * +from litex.gen.genlib.misc import timeline -from misoc.interconnect import wishbone -from misoc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus +from litex.soc.interconnect import wishbone +from litex.soc.interconnect.csr import AutoCSR, CSRStorage, CSRStatus _FAST_READ = 0x0b diff --git a/litex/soc/misoc/cores/gpio.py b/litex/soc/cores/gpio.py similarity index 88% rename from litex/soc/misoc/cores/gpio.py rename to litex/soc/cores/gpio.py index 2e99c27f..463e1e20 100644 --- a/litex/soc/misoc/cores/gpio.py +++ b/litex/soc/cores/gpio.py @@ -1,7 +1,7 @@ -from migen import * -from migen.genlib.cdc import MultiReg +from litex.gen import * +from litex.gen.genlib.cdc import MultiReg -from misoc.interconnect.csr import * +from litex.soc.interconnect.csr import * class GPIOIn(Module, AutoCSR): diff --git a/litex/soc/misoc/cores/identifier.py b/litex/soc/cores/identifier.py similarity index 82% rename from litex/soc/misoc/cores/identifier.py rename to litex/soc/cores/identifier.py index 5088fd32..2ed151f8 100644 --- a/litex/soc/misoc/cores/identifier.py +++ b/litex/soc/cores/identifier.py @@ -1,6 +1,6 @@ -from migen import * +from litex.gen import * -from misoc.interconnect.csr import * +from litex.soc.interconnect.csr import * class Identifier(Module, AutoCSR): diff --git a/litex/soc/misoc/tools/__init__.py b/litex/soc/cores/sdram/__init__.py similarity index 100% rename from litex/soc/misoc/tools/__init__.py rename to litex/soc/cores/sdram/__init__.py diff --git a/litex/soc/misoc/cores/dfii.py b/litex/soc/cores/sdram/dfii.py similarity index 96% rename from litex/soc/misoc/cores/dfii.py rename to litex/soc/cores/sdram/dfii.py index 745e3342..e0b58047 100644 --- a/litex/soc/misoc/cores/dfii.py +++ b/litex/soc/cores/sdram/dfii.py @@ -1,7 +1,7 @@ from migen import * -from misoc.interconnect import dfi -from misoc.interconnect.csr import * +from litex.soc.interconnect import dfi +from litex.soc.interconnect.csr import * class PhaseInjector(Module, AutoCSR): diff --git a/litex/soc/cores/sdram/lasmicon/__init__.py b/litex/soc/cores/sdram/lasmicon/__init__.py new file mode 100644 index 00000000..9242b76b --- /dev/null +++ b/litex/soc/cores/sdram/lasmicon/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.sdram.lasmicon.core import ControllerSettings, LASMIcon diff --git a/litex/soc/misoc/cores/lasmicon/bankmachine.py b/litex/soc/cores/sdram/lasmicon/bankmachine.py similarity index 95% rename from litex/soc/misoc/cores/lasmicon/bankmachine.py rename to litex/soc/cores/sdram/lasmicon/bankmachine.py index 853e7d9a..7a9b26c8 100644 --- a/litex/soc/misoc/cores/lasmicon/bankmachine.py +++ b/litex/soc/cores/sdram/lasmicon/bankmachine.py @@ -1,9 +1,9 @@ -from migen import * -from migen.genlib.roundrobin import * -from migen.genlib.fsm import FSM, NextState -from migen.genlib.fifo import SyncFIFO +from litex.gen import * +from litex.gen.genlib.roundrobin import * +from litex.gen.genlib.fsm import FSM, NextState +from litex.gen.genlib.fifo import SyncFIFO -from misoc.cores.lasmicon.multiplexer import * +from litex.soc.cores.sdram.lasmicon.multiplexer import * class _AddressSlicer: diff --git a/litex/soc/misoc/cores/lasmicon/core.py b/litex/soc/cores/sdram/lasmicon/core.py similarity index 89% rename from litex/soc/misoc/cores/lasmicon/core.py rename to litex/soc/cores/sdram/lasmicon/core.py index bd53825e..a6625015 100644 --- a/litex/soc/misoc/cores/lasmicon/core.py +++ b/litex/soc/cores/sdram/lasmicon/core.py @@ -1,9 +1,9 @@ -from migen import * +from litex.gen import * -from misoc.interconnect import dfi, lasmi_bus -from misoc.cores.lasmicon.refresher import * -from misoc.cores.lasmicon.bankmachine import * -from misoc.cores.lasmicon.multiplexer import * +from litex.soc.interconnect import dfi, lasmi_bus +from litex.soc.cores.sdram.lasmicon.refresher import * +from litex.soc.cores.sdram.lasmicon.bankmachine import * +from litex.soc.cores.sdram.lasmicon.multiplexer import * class ControllerSettings: diff --git a/litex/soc/misoc/cores/lasmicon/multiplexer.py b/litex/soc/cores/sdram/lasmicon/multiplexer.py similarity index 97% rename from litex/soc/misoc/cores/lasmicon/multiplexer.py rename to litex/soc/cores/sdram/lasmicon/multiplexer.py index 07d0da73..af118c50 100644 --- a/litex/soc/misoc/cores/lasmicon/multiplexer.py +++ b/litex/soc/cores/sdram/lasmicon/multiplexer.py @@ -1,12 +1,12 @@ from functools import reduce from operator import or_, and_ -from migen import * -from migen.genlib.roundrobin import * -from migen.genlib.fsm import FSM, NextState +from litex.gen import * +from litex.gen.genlib.roundrobin import * +from litex.gen.genlib.fsm import FSM, NextState -from misoc.cores.lasmicon.perf import Bandwidth -from misoc.interconnect.csr import AutoCSR +from litex.soc.cores.sdram.lasmicon.perf import Bandwidth +from litex.soc.interconnect.csr import AutoCSR class CommandRequest: diff --git a/litex/soc/misoc/cores/lasmicon/perf.py b/litex/soc/cores/sdram/lasmicon/perf.py similarity index 95% rename from litex/soc/misoc/cores/lasmicon/perf.py rename to litex/soc/cores/sdram/lasmicon/perf.py index 2e3fe847..dbd62d3a 100644 --- a/litex/soc/misoc/cores/lasmicon/perf.py +++ b/litex/soc/cores/sdram/lasmicon/perf.py @@ -1,6 +1,6 @@ -from migen import * +from litex.gen import * -from misoc.interconnect.csr import * +from litex.soc.interconnect.csr import * class Bandwidth(Module, AutoCSR): diff --git a/litex/soc/misoc/cores/lasmicon/refresher.py b/litex/soc/cores/sdram/lasmicon/refresher.py similarity index 91% rename from litex/soc/misoc/cores/lasmicon/refresher.py rename to litex/soc/cores/sdram/lasmicon/refresher.py index cac98906..e4c5da92 100644 --- a/litex/soc/misoc/cores/lasmicon/refresher.py +++ b/litex/soc/cores/sdram/lasmicon/refresher.py @@ -1,8 +1,8 @@ -from migen import * -from migen.genlib.misc import timeline -from migen.genlib.fsm import FSM +from litex.gen import * +from litex.gen.genlib.misc import timeline +from litex.gen.genlib.fsm import FSM -from misoc.cores.lasmicon.multiplexer import * +from litex.soc.cores.sdram.lasmicon.multiplexer import * class Refresher(Module): diff --git a/litex/soc/cores/sdram/minicon/__init__.py b/litex/soc/cores/sdram/minicon/__init__.py new file mode 100644 index 00000000..4b265e26 --- /dev/null +++ b/litex/soc/cores/sdram/minicon/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.sdram.minicon.core import Minicon diff --git a/litex/soc/misoc/cores/minicon/core.py b/litex/soc/cores/sdram/minicon/core.py similarity index 97% rename from litex/soc/misoc/cores/minicon/core.py rename to litex/soc/cores/sdram/minicon/core.py index 871d087b..13600b7f 100644 --- a/litex/soc/misoc/cores/minicon/core.py +++ b/litex/soc/cores/sdram/minicon/core.py @@ -1,12 +1,12 @@ from functools import reduce from operator import or_ -from migen import * -from migen.genlib.fsm import FSM, NextState -from migen.genlib.misc import WaitTimer +from litex.gen import * +from litex.gen.genlib.fsm import FSM, NextState +from litex.gen.genlib.misc import WaitTimer -from misoc.interconnect import dfi as dfibus -from misoc.interconnect import wishbone +from litex.soc.interconnect import dfi as dfibus +from litex.soc.interconnect import wishbone class _AddressSlicer: diff --git a/litex/soc/misoc/cores/sdram_model.py b/litex/soc/cores/sdram/model.py similarity index 96% rename from litex/soc/misoc/cores/sdram_model.py rename to litex/soc/cores/sdram/model.py index 28bcab11..a04b0980 100644 --- a/litex/soc/misoc/cores/sdram_model.py +++ b/litex/soc/cores/sdram/model.py @@ -4,12 +4,12 @@ # SDRAM simulation PHY at DFI level # tested with SDR/DDR/DDR2/LPDDR/DDR3 # TODO: -# - add $display support to Migen and manage timing violations? +# - add $display support to LiteX gen and manage timing violations? -from migen import * -from migen.fhdl.specials import * -from misoc.mem.sdram.phy.dfi import * -from misoc.mem import sdram +from litex.gen import * +from litex.gen.fhdl.specials import * +from litex.soc.mem.sdram.phy.dfi import * +from litex.soc.mem import sdram class Bank(Module): diff --git a/litex/soc/cores/sdram/phy/__init__.py b/litex/soc/cores/sdram/phy/__init__.py new file mode 100644 index 00000000..551c3091 --- /dev/null +++ b/litex/soc/cores/sdram/phy/__init__.py @@ -0,0 +1,3 @@ +from litex.soc.cores.sdram.phy.gensdrphy import GENSDRPHY +from litex.soc.cores.sdram.phy.s6ddrphy import S6HalfRateDDRPHY, S6QuarterRateDDRPHY +from litex.soc.cores.sdram.phy.k7ddrphy import K7DDRPHY diff --git a/litex/soc/misoc/cores/sdram_phy/gensdrphy.py b/litex/soc/cores/sdram/phy/gensdrphy.py similarity index 92% rename from litex/soc/misoc/cores/sdram_phy/gensdrphy.py rename to litex/soc/cores/sdram/phy/gensdrphy.py index b704a6bd..303faeb0 100644 --- a/litex/soc/misoc/cores/sdram_phy/gensdrphy.py +++ b/litex/soc/cores/sdram/phy/gensdrphy.py @@ -21,12 +21,12 @@ # This PHY only supports CAS Latency 2. # -from migen import * -from migen.genlib.record import * -from migen.fhdl.specials import Tristate +from litex.gen import * +from litex.gen.genlib.record import * +from litex.gen.fhdl.specials import Tristate -from misoc.interconnect.dfi import * -from misoc.cores import sdram_settings +from litex.soc.interconnect.dfi import * +from litex.soc.cores.sdram import settings as sdram_settings class GENSDRPHY(Module): diff --git a/litex/soc/misoc/cores/sdram_phy/k7ddrphy.py b/litex/soc/cores/sdram/phy/k7ddrphy.py similarity index 98% rename from litex/soc/misoc/cores/sdram_phy/k7ddrphy.py rename to litex/soc/cores/sdram/phy/k7ddrphy.py index bb91ef0b..385bbc9b 100644 --- a/litex/soc/misoc/cores/sdram_phy/k7ddrphy.py +++ b/litex/soc/cores/sdram/phy/k7ddrphy.py @@ -1,10 +1,10 @@ # tCK=5ns CL=7 CWL=6 -from migen import * +from litex.gen import * -from misoc.interconnect.dfi import * -from misoc.interconnect.csr import * -from misoc.cores import sdram_settings +from litex.soc.interconnect.dfi import * +from litex.soc.interconnect.csr import * +from litex.soc.cores.sdram import settings as sdram_settings class K7DDRPHY(Module, AutoCSR): diff --git a/litex/soc/misoc/cores/sdram_phy/s6ddrphy.py b/litex/soc/cores/sdram/phy/s6ddrphy.py similarity index 99% rename from litex/soc/misoc/cores/sdram_phy/s6ddrphy.py rename to litex/soc/cores/sdram/phy/s6ddrphy.py index decd6ada..dfd3e0a2 100644 --- a/litex/soc/misoc/cores/sdram_phy/s6ddrphy.py +++ b/litex/soc/cores/sdram/phy/s6ddrphy.py @@ -19,11 +19,11 @@ from functools import reduce from operator import or_ -from migen import * -from migen.genlib.record import * +from litex.gen import * +from litex.gen.genlib.record import * -from misoc.interconnect.dfi import * -from misoc.cores import sdram_settings +from litex.soc.interconnect.dfi import * +from litex.soc.cores.sdram import settings as sdram_settings class S6HalfRateDDRPHY(Module): diff --git a/litex/soc/misoc/cores/sdram_settings.py b/litex/soc/cores/sdram/settings.py similarity index 99% rename from litex/soc/misoc/cores/sdram_settings.py rename to litex/soc/cores/sdram/settings.py index ce575a4a..0e99ac12 100644 --- a/litex/soc/misoc/cores/sdram_settings.py +++ b/litex/soc/cores/sdram/settings.py @@ -1,7 +1,7 @@ from math import ceil from collections import namedtuple -from migen import * +from litex.gen import * PhySettingsT = namedtuple("PhySettings", "memtype dfi_databits nphases rdphase wrphase rdcmdphase wrcmdphase cl cwl read_latency write_latency") diff --git a/litex/soc/misoc/cores/sdram_tester.py b/litex/soc/cores/sdram/tester.py similarity index 94% rename from litex/soc/misoc/cores/sdram_tester.py rename to litex/soc/cores/sdram/tester.py index 73d0a896..28b0318e 100644 --- a/litex/soc/misoc/cores/sdram_tester.py +++ b/litex/soc/cores/sdram/tester.py @@ -1,10 +1,10 @@ from functools import reduce from operator import xor -from migen import * +from litex.gen import * -from misoc.interconnect.csr import * -from misoc.interconnect import dma_lasmi +from litex.soc.interconnect.csr import * +from litex.soc.interconnect import dma_lasmi # TODO: implement or replace DMAControllers in MiSoC @@ -114,8 +114,8 @@ class _LFSRTB(Module): print("{0:032x}".format(selfp.dut.o)) if __name__ == "__main__": - from migen.fhdl import verilog - from migen.sim.generic import run_simulation + from litex.gen.fhdl import verilog + from litex.gen.sim.generic import run_simulation lfsr = LFSR(3, 4, [3, 2]) print(verilog.convert(lfsr, ios={lfsr.ce, lfsr.reset, lfsr.o})) diff --git a/litex/soc/cores/spi/__init__.py b/litex/soc/cores/spi/__init__.py new file mode 100644 index 00000000..fe71de13 --- /dev/null +++ b/litex/soc/cores/spi/__init__.py @@ -0,0 +1 @@ +from litex.soc.spi.core import SPIMaster diff --git a/litex/soc/misoc/cores/spi/core.py b/litex/soc/cores/spi/core.py similarity index 97% rename from litex/soc/misoc/cores/spi/core.py rename to litex/soc/cores/spi/core.py index 1658d949..56db5020 100644 --- a/litex/soc/misoc/cores/spi/core.py +++ b/litex/soc/cores/spi/core.py @@ -1,6 +1,6 @@ -from migen import * -from migen.bank.description import * -from migen.genlib.fsm import FSM, NextState +from litex.gen import * +from litex.gen.bank.description import * +from litex.gen.genlib.fsm import FSM, NextState class SPIMaster(Module, AutoCSR): diff --git a/litex/soc/misoc/cores/spi/test.py b/litex/soc/cores/spi/test.py similarity index 93% rename from litex/soc/misoc/cores/spi/test.py rename to litex/soc/cores/spi/test.py index e0febf53..bed69b14 100644 --- a/litex/soc/misoc/cores/spi/test.py +++ b/litex/soc/cores/spi/test.py @@ -1,8 +1,8 @@ -from migen import * -from migen.genlib.record import * -from migen.sim.generic import run_simulation +from litex.gen import * +from litex.gen.genlib.record import * +from litex.gen.sim.generic import run_simulation -from misoc.com.spi import SPIMaster +from litex.soc.com.spi import SPIMaster class SPISlave(Module): diff --git a/litex/soc/misoc/cores/timer.py b/litex/soc/cores/timer.py similarity index 88% rename from litex/soc/misoc/cores/timer.py rename to litex/soc/cores/timer.py index 64c86238..d98a85e9 100644 --- a/litex/soc/misoc/cores/timer.py +++ b/litex/soc/cores/timer.py @@ -1,7 +1,7 @@ -from migen import * +from litex.gen import * -from misoc.interconnect.csr import * -from misoc.interconnect.csr_eventmanager import * +from litex.soc.interconnect.csr import * +from litex.soc.interconnect.csr_eventmanager import * class Timer(Module, AutoCSR): diff --git a/litex/soc/cores/uart/__init__.py b/litex/soc/cores/uart/__init__.py new file mode 100644 index 00000000..94097056 --- /dev/null +++ b/litex/soc/cores/uart/__init__.py @@ -0,0 +1 @@ +from litex.soc.cores.uart.core import UART, RS232PHY diff --git a/litex/soc/misoc/cores/uart/core.py b/litex/soc/cores/uart/core.py similarity index 94% rename from litex/soc/misoc/cores/uart/core.py rename to litex/soc/cores/uart/core.py index b6a2a703..ad283ef0 100644 --- a/litex/soc/misoc/cores/uart/core.py +++ b/litex/soc/cores/uart/core.py @@ -1,10 +1,10 @@ -from migen import * -from migen.genlib.record import Record -from migen.genlib.cdc import MultiReg +from litex.gen import * +from litex.gen.genlib.record import Record +from litex.gen.genlib.cdc import MultiReg -from misoc.interconnect.csr import * -from misoc.interconnect.csr_eventmanager import * -from misoc.interconnect.stream import Source, Sink, SyncFIFO, AsyncFIFO +from litex.soc.interconnect.csr import * +from litex.soc.interconnect.csr_eventmanager import * +from litex.soc.interconnect.stream import Source, Sink, SyncFIFO, AsyncFIFO class RS232PHYRX(Module): diff --git a/litex/soc/integration/__init__.py b/litex/soc/integration/__init__.py new file mode 100644 index 00000000..8a97adbd --- /dev/null +++ b/litex/soc/integration/__init__.py @@ -0,0 +1,2 @@ +from litex.soc.integration.soc_core import SoCCore +from litex.soc.integration.soc_sdram import SoCSDRAM diff --git a/litex/soc/misoc/integration/builder.py b/litex/soc/integration/builder.py similarity index 93% rename from litex/soc/misoc/integration/builder.py rename to litex/soc/integration/builder.py index 6594673d..9aca14b3 100644 --- a/litex/soc/misoc/integration/builder.py +++ b/litex/soc/integration/builder.py @@ -2,15 +2,15 @@ import os import subprocess import struct -from misoc.integration import cpu_interface, soc_sdram, sdram_init +from litex.soc.integration import cpu_interface, soc_sdram, sdram_init -__all__ = ["misoc_software_packages", "misoc_directory", +__all__ = ["soc_software_packages", "soc_directory", "Builder", "builder_args", "builder_argdict"] # in build order (for dependencies) -misoc_software_packages = [ +soc_software_packages = [ "libbase", "libcompiler_rt", "libdyld", @@ -20,7 +20,7 @@ misoc_software_packages = [ ] -misoc_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) +soc_directory = os.path.abspath(os.path.join(os.path.dirname(__file__), "..")) def _makefile_escape(s): @@ -34,7 +34,7 @@ class Builder: csr_csv=None): self.soc = soc if output_dir is None: - output_dir = "misoc_{}_{}".format( + output_dir = "soc_{}_{}".format( soc.__class__.__name__.lower(), soc.platform.name) # From Python doc: makedirs() will become confused if the path @@ -46,9 +46,9 @@ class Builder: self.csr_csv = csr_csv self.software_packages = [] - for name in misoc_software_packages: + for name in soc_software_packages: self.add_software_package( - name, os.path.join(misoc_directory, "software", name)) + name, os.path.join(soc_directory, "software", name)) def add_software_package(self, name, src_dir): self.software_packages.append((name, src_dir)) @@ -72,7 +72,7 @@ class Builder: f.write("{}={}\n".format(k, _makefile_escape(v))) for k, v in cpu_interface.get_cpu_mak(cpu_type): define(k, v) - define("MISOC_DIRECTORY", misoc_directory) + define("SOC_DIRECTORY", soc_directory) define("BUILDINC_DIRECTORY", buildinc_dir) for name, src_dir in self.software_packages: define(name.upper() + "_DIRECTORY", src_dir) diff --git a/litex/soc/misoc/integration/cpu_interface.py b/litex/soc/integration/cpu_interface.py similarity index 98% rename from litex/soc/misoc/integration/cpu_interface.py rename to litex/soc/integration/cpu_interface.py index 0514b4ee..4648b1b8 100644 --- a/litex/soc/misoc/integration/cpu_interface.py +++ b/litex/soc/integration/cpu_interface.py @@ -1,6 +1,6 @@ -from migen import * +from litex.gen import * -from misoc.interconnect.csr import CSRStatus +from litex.soc.interconnect.csr import CSRStatus def get_cpu_mak(cpu): diff --git a/litex/soc/misoc/integration/sdram_init.py b/litex/soc/integration/sdram_init.py similarity index 99% rename from litex/soc/misoc/integration/sdram_init.py rename to litex/soc/integration/sdram_init.py index 8ca1db00..1f73c1ec 100644 --- a/litex/soc/misoc/integration/sdram_init.py +++ b/litex/soc/integration/sdram_init.py @@ -1,4 +1,4 @@ -from migen import log2_int +from litex.gen import log2_int def get_sdram_phy_header(sdram_phy_settings): diff --git a/litex/soc/misoc/integration/soc_core.py b/litex/soc/integration/soc_core.py similarity index 97% rename from litex/soc/misoc/integration/soc_core.py rename to litex/soc/integration/soc_core.py index cf8bbe56..315af070 100644 --- a/litex/soc/misoc/integration/soc_core.py +++ b/litex/soc/integration/soc_core.py @@ -1,9 +1,10 @@ from operator import itemgetter -from migen import * +from litex.gen import * -from misoc.cores import lm32, mor1kx, identifier, timer, uart -from misoc.interconnect import wishbone, csr_bus, wishbone2csr +from litex.soc.cores import identifier, timer, uart +from litex.soc.cores.cpu import lm32, mor1kx +from litex.soc.interconnect import wishbone, csr_bus, wishbone2csr __all__ = ["mem_decoder", "SoCCore", "soc_core_args", "soc_core_argdict"] diff --git a/litex/soc/misoc/integration/soc_sdram.py b/litex/soc/integration/soc_sdram.py similarity index 90% rename from litex/soc/misoc/integration/soc_sdram.py rename to litex/soc/integration/soc_sdram.py index 88957d33..8ad63009 100644 --- a/litex/soc/misoc/integration/soc_sdram.py +++ b/litex/soc/integration/soc_sdram.py @@ -1,10 +1,10 @@ -from migen import * -from migen.genlib.record import * +from litex.gen import * +from litex.gen.genlib.record import * -from misoc.interconnect import wishbone, wishbone2lasmi, lasmi_bus -from misoc.interconnect.csr import AutoCSR -from misoc.cores import dfii, minicon, lasmicon -from misoc.integration.soc_core import * +from litex.soc.interconnect import wishbone, wishbone2lasmi, lasmi_bus +from litex.soc.interconnect.csr import AutoCSR +from litex.soc.cores.sdram import dfii, minicon, lasmicon +from litex.soc.integration.soc_core import * __all__ = ["SoCSDRAM", "soc_sdram_args", "soc_sdram_argdict"] @@ -43,7 +43,7 @@ class SoCSDRAM(SoCCore): def __init__(self, platform, clk_freq, l2_size=8192, **kwargs): SoCCore.__init__(self, platform, clk_freq, **kwargs) self.l2_size = l2_size - + self._sdram_phy = [] self._wb_sdram_ifs = [] self._wb_sdram = wishbone.Interface() @@ -82,9 +82,9 @@ class SoCSDRAM(SoCCore): # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache. # Issue is reported to Xilinx and should be fixed in next releases (2015.2?). # Remove this workaround when fixed by Xilinx. - from migen.build.xilinx.vivado import XilinxVivadoToolchain + from litex.build.xilinx.vivado import XilinxVivadoToolchain if isinstance(self.platform.toolchain, XilinxVivadoToolchain): - from migen.fhdl.simplify import FullMemoryWE + from litex.gen.fhdl.simplify import FullMemoryWE self.submodules.l2_cache = FullMemoryWE()(l2_cache) else: self.submodules.l2_cache = l2_cache @@ -95,9 +95,9 @@ class SoCSDRAM(SoCCore): # XXX Vivado ->2015.1 workaround, Vivado is not able to map correctly our L2 cache. # Issue is reported to Xilinx and should be fixed in next releases (2015.2?). # Remove this workaround when fixed by Xilinx. - from migen.build.xilinx.vivado import XilinxVivadoToolchain + from litex.build.xilinx.vivado import XilinxVivadoToolchain if isinstance(self.platform.toolchain, XilinxVivadoToolchain): - from migen.fhdl.simplify import FullMemoryWE + from litex.gen.fhdl.simplify import FullMemoryWE self.submodules.l2_cache = FullMemoryWE()(l2_cache) else: self.submodules.l2_cache = l2_cache diff --git a/migen/build/__init__.py b/litex/soc/interconnect/__init__.py similarity index 100% rename from migen/build/__init__.py rename to litex/soc/interconnect/__init__.py diff --git a/litex/soc/misoc/interconnect/csr.py b/litex/soc/interconnect/csr.py similarity index 97% rename from litex/soc/misoc/interconnect/csr.py rename to litex/soc/interconnect/csr.py index 8183b2e0..c4458cde 100644 --- a/litex/soc/misoc/interconnect/csr.py +++ b/litex/soc/interconnect/csr.py @@ -1,6 +1,6 @@ -from migen import * -from migen.util.misc import xdir -from migen.fhdl.tracer import get_obj_var_name +from litex.gen import * +from litex.gen.util.misc import xdir +from litex.gen.fhdl.tracer import get_obj_var_name class _CSRBase(DUID): diff --git a/litex/soc/misoc/interconnect/csr_bus.py b/litex/soc/interconnect/csr_bus.py similarity index 96% rename from litex/soc/misoc/interconnect/csr_bus.py rename to litex/soc/interconnect/csr_bus.py index 5b634f58..b27c256f 100644 --- a/litex/soc/misoc/interconnect/csr_bus.py +++ b/litex/soc/interconnect/csr_bus.py @@ -1,10 +1,10 @@ -from migen import * -from migen.genlib.record import * -from migen.genlib.misc import chooser -from migen.util.misc import xdir +from litex.gen import * +from litex.gen.genlib.record import * +from litex.gen.genlib.misc import chooser +from litex.gen.util.misc import xdir -from misoc.interconnect import csr -from misoc.interconnect.csr import CSRStorage +from litex.soc.interconnect import csr +from litex.soc.interconnect.csr import CSRStorage _layout = [ diff --git a/litex/soc/misoc/interconnect/csr_eventmanager.py b/litex/soc/interconnect/csr_eventmanager.py similarity index 96% rename from litex/soc/misoc/interconnect/csr_eventmanager.py rename to litex/soc/interconnect/csr_eventmanager.py index 44b0a592..12b85a0a 100644 --- a/litex/soc/misoc/interconnect/csr_eventmanager.py +++ b/litex/soc/interconnect/csr_eventmanager.py @@ -1,10 +1,10 @@ from functools import reduce from operator import or_ -from migen import * -from migen.util.misc import xdir +from litex.gen import * +from litex.gen.util.misc import xdir -from misoc.interconnect.csr import * +from litex.soc.interconnect.csr import * class _EventSource(DUID): diff --git a/litex/soc/misoc/interconnect/dfi.py b/litex/soc/interconnect/dfi.py similarity index 97% rename from litex/soc/misoc/interconnect/dfi.py rename to litex/soc/interconnect/dfi.py index aae56b0d..25812122 100644 --- a/litex/soc/misoc/interconnect/dfi.py +++ b/litex/soc/interconnect/dfi.py @@ -1,5 +1,5 @@ -from migen import * -from migen.genlib.record import * +from litex.gen import * +from litex.gen.genlib.record import * def phase_cmd_description(addressbits, bankbits): diff --git a/litex/soc/misoc/interconnect/dma_lasmi.py b/litex/soc/interconnect/dma_lasmi.py similarity index 97% rename from litex/soc/misoc/interconnect/dma_lasmi.py rename to litex/soc/interconnect/dma_lasmi.py index ce3937bc..1d1e9998 100644 --- a/litex/soc/misoc/interconnect/dma_lasmi.py +++ b/litex/soc/interconnect/dma_lasmi.py @@ -1,5 +1,5 @@ -from migen import * -from migen.genlib.fifo import SyncFIFO +from litex.gen import * +from litex.gen.genlib.fifo import SyncFIFO class Reader(Module): diff --git a/litex/soc/misoc/interconnect/lasmi_bus.py b/litex/soc/interconnect/lasmi_bus.py similarity index 98% rename from litex/soc/misoc/interconnect/lasmi_bus.py rename to litex/soc/interconnect/lasmi_bus.py index c8d2ded2..841b72b1 100644 --- a/litex/soc/misoc/interconnect/lasmi_bus.py +++ b/litex/soc/interconnect/lasmi_bus.py @@ -1,9 +1,9 @@ from functools import reduce from operator import or_ -from migen import * -from migen.genlib import roundrobin -from migen.genlib.record import * +from litex.gen import * +from litex.gen.genlib import roundrobin +from litex.gen.genlib.record import * class Interface(Record): diff --git a/litex/soc/misoc/interconnect/stream.py b/litex/soc/interconnect/stream.py similarity index 98% rename from litex/soc/misoc/interconnect/stream.py rename to litex/soc/interconnect/stream.py index 0c708420..a1b44c2e 100644 --- a/litex/soc/misoc/interconnect/stream.py +++ b/litex/soc/interconnect/stream.py @@ -1,6 +1,6 @@ -from migen import * -from migen.genlib.record import * -from migen.genlib import fifo +from litex.gen import * +from litex.gen.genlib.record import * +from litex.gen.genlib import fifo def _make_m2s(layout): @@ -154,7 +154,7 @@ class Demultiplexer(Module): # XXX from copy import copy -from migen.util.misc import xdir +from litex.gen.util.misc import xdir def pack_layout(l, n): return [("chunk"+str(i), l) for i in range(n)] diff --git a/litex/soc/misoc/interconnect/wishbone.py b/litex/soc/interconnect/wishbone.py similarity index 97% rename from litex/soc/misoc/interconnect/wishbone.py rename to litex/soc/interconnect/wishbone.py index d24148be..a2070fa4 100644 --- a/litex/soc/misoc/interconnect/wishbone.py +++ b/litex/soc/interconnect/wishbone.py @@ -1,13 +1,13 @@ from functools import reduce from operator import or_ -from migen import * -from migen.genlib import roundrobin -from migen.genlib.record import * -from migen.genlib.misc import split, displacer, chooser -from migen.genlib.fsm import FSM, NextState +from litex.gen import * +from litex.gen.genlib import roundrobin +from litex.gen.genlib.record import * +from litex.gen.genlib.misc import split, displacer, chooser +from litex.gen.genlib.fsm import FSM, NextState -from misoc.interconnect import csr +from litex.soc.interconnect import csr # TODO: rewrite without FlipFlop and Counter @@ -164,8 +164,6 @@ class DownConverter(Module): Read from master are splitted in N reads to the the slave. Read datas from the slave are cached before being presented concatenated on the last access. - TODO: - Manage err signal? (Not implemented since we generally don't use it on Migen/MiSoC modules) """ def __init__(self, master, slave): dw_from = len(master.dat_r) @@ -271,8 +269,6 @@ class UpConverter(Module): Cache is refilled only at the beginning of each burst, the subsequent reads of a burst use the cached data. - TODO: - Manage err signal? (Not implemented since we generally don't use it on Migen/MiSoC modules) """ def __init__(self, master, slave): dw_from = len(master.dat_r) diff --git a/litex/soc/misoc/interconnect/wishbone2csr.py b/litex/soc/interconnect/wishbone2csr.py similarity index 86% rename from litex/soc/misoc/interconnect/wishbone2csr.py rename to litex/soc/interconnect/wishbone2csr.py index b065724a..25efdc6f 100644 --- a/litex/soc/misoc/interconnect/wishbone2csr.py +++ b/litex/soc/interconnect/wishbone2csr.py @@ -1,7 +1,7 @@ -from migen import * -from migen.genlib.misc import timeline +from litex.gen import * +from litex.gen.genlib.misc import timeline -from misoc.interconnect import csr_bus, wishbone +from litex.soc.interconnect import csr_bus, wishbone class WB2CSR(Module): diff --git a/litex/soc/misoc/interconnect/wishbone2lasmi.py b/litex/soc/interconnect/wishbone2lasmi.py similarity index 94% rename from litex/soc/misoc/interconnect/wishbone2lasmi.py rename to litex/soc/interconnect/wishbone2lasmi.py index 9c95689c..bd139afa 100644 --- a/litex/soc/misoc/interconnect/wishbone2lasmi.py +++ b/litex/soc/interconnect/wishbone2lasmi.py @@ -1,5 +1,5 @@ -from migen import * -from migen.genlib.fsm import FSM, NextState +from litex.gen import * +from litex.gen.genlib.fsm import FSM, NextState class WB2LASMI(Module): diff --git a/litex/soc/misoc/cores/dvi_sampler/__init__.py b/litex/soc/misoc/cores/dvi_sampler/__init__.py deleted file mode 100644 index 60f4b375..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.dvi_sampler.core import DVISampler diff --git a/litex/soc/misoc/cores/dvi_sampler/analysis.py b/litex/soc/misoc/cores/dvi_sampler/analysis.py deleted file mode 100644 index d6084517..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/analysis.py +++ /dev/null @@ -1,207 +0,0 @@ -from migen import * -from migen.genlib.cdc import MultiReg, PulseSynchronizer -from migen.genlib.fifo import AsyncFIFO -from migen.genlib.record import Record - -from misoc.interconnect.csr import * -from misoc.cores.dvi_sampler.common import channel_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, word_width, fifo_depth): - # 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 - word_layout = [("sof", 1), ("pixels", word_width)] - self.frame = Source(word_layout) - self.busy = Signal() - - self._overflow = CSR() - - ### - - # start of frame detection - vsync_r = Signal() - new_frame = Signal() - self.comb += new_frame.eq(self.vsync & ~vsync_r) - self.sync.pix += vsync_r.eq(self.vsync) - - # pack pixels into words - cur_word = Signal(word_width) - cur_word_valid = Signal() - encoded_pixel = Signal(24) - self.comb += encoded_pixel.eq(Cat(self.b, self.g, self.r)) - pack_factor = word_width//24 - assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2 - pack_counter = Signal(max=pack_factor) - self.sync.pix += [ - cur_word_valid.eq(0), - If(new_frame, - cur_word_valid.eq(pack_counter == (pack_factor - 1)), - pack_counter.eq(0), - ).Elif(self.valid_i & self.de, - [If(pack_counter == (pack_factor-i-1), - cur_word[24*i:24*(i+1)].eq(encoded_pixel)) for i in range(pack_factor)], - cur_word_valid.eq(pack_counter == (pack_factor - 1)), - pack_counter.eq(pack_counter + 1) - ) - ] - - # FIFO - fifo = RenameClockDomains(AsyncFIFO(word_layout, fifo_depth), - {"write": "pix", "read": "sys"}) - self.submodules += fifo - self.comb += [ - fifo.din.pixels.eq(cur_word), - fifo.we.eq(cur_word_valid) - ] - self.sync.pix += \ - If(new_frame, - fifo.din.sof.eq(1) - ).Elif(cur_word_valid, - fifo.din.sof.eq(0) - ) - self.comb += [ - self.frame.stb.eq(fifo.readable), - self.frame.payload.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._overflow.w.eq(sys_overflow & ~overflow_mask), - self.overflow_reset.i.eq(self._overflow.re) - ] - self.sync += \ - If(self._overflow.re, - overflow_mask.eq(1) - ).Elif(self.overflow_reset_ack.o, - overflow_mask.eq(0) - ) diff --git a/litex/soc/misoc/cores/dvi_sampler/chansync.py b/litex/soc/misoc/cores/dvi_sampler/chansync.py deleted file mode 100644 index 093db3ec..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/chansync.py +++ /dev/null @@ -1,134 +0,0 @@ -from functools import reduce -from operator import or_, and_ - -from migen import * -from migen.genlib.cdc import MultiReg -from migen.genlib.fifo import _inc -from migen.genlib.record import Record, layout_len - -from misoc.interconnect.csr import * -from misoc.cores.dvi_sampler.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._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(reduce(and_, lst_control)), - some_control.eq(reduce(or_, 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._channels_synced.status) - - -class _TB(Module): - def __init__(self, test_seq_it): - self.test_seq_it = test_seq_it - - self.submodules.chansync = RenameClockDomains(ChanSync(), {"pix": "sys"}) - self.comb += self.chansync.valid_i.eq(1) - - def do_simulation(self, selfp): - try: - de0, de1, de2 = next(self.test_seq_it) - except StopIteration: - raise StopSimulation - - selfp.chansync.data_in0.de = de0 - selfp.chansync.data_in1.de = de1 - selfp.chansync.data_in2.de = de2 - selfp.chansync.data_in0.d = selfp.simulator.cycle_counter - selfp.chansync.data_in1.d = selfp.simulator.cycle_counter - selfp.chansync.data_in2.d = selfp.simulator.cycle_counter - - out0 = selfp.chansync.data_out0.d - out1 = selfp.chansync.data_out1.d - out2 = selfp.chansync.data_out2.d - - print("{0:5} {1:5} {2:5}".format(out0, out1, out2)) - -if __name__ == "__main__": - from migen.sim.generic import run_simulation - - test_seq = [ - (1, 1, 1), - (1, 1, 0), - (0, 0, 0), - (0, 0, 0), - (0, 0, 1), - (1, 1, 1), - (1, 1, 1), - ] - tb = _TB(iter(test_seq*2)) - run_simulation(tb) diff --git a/litex/soc/misoc/cores/dvi_sampler/charsync.py b/litex/soc/misoc/cores/dvi_sampler/charsync.py deleted file mode 100644 index 7912fb4b..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/charsync.py +++ /dev/null @@ -1,56 +0,0 @@ -from functools import reduce -from operator import or_ - -from migen import * -from migen.genlib.cdc import MultiReg - -from misoc.interconnect.csr import * -from misoc.cores.dvi_sampler.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._char_synced = CSRStatus() - self._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(reduce(or_, [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._char_synced.status) - self.specials += MultiReg(word_sel, self._ctl_pos.status) - - self.sync.pix += self.data.eq(raw >> word_sel) diff --git a/litex/soc/misoc/cores/dvi_sampler/clocking.py b/litex/soc/misoc/cores/dvi_sampler/clocking.py deleted file mode 100644 index 9c9c2ac0..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/clocking.py +++ /dev/null @@ -1,81 +0,0 @@ -from migen import * -from migen.genlib.cdc import MultiReg - -from misoc.interconnect.csr import * - - -class Clocking(Module, AutoCSR): - def __init__(self, pads): - self._pll_reset = CSRStorage(reset=1) - self._locked = CSRStatus() - - # DRP - self._pll_adr = CSRStorage(5) - self._pll_dat_r = CSRStatus(16) - self._pll_dat_w = CSRStorage(16) - self._pll_read = CSR() - self._pll_write = CSR() - self._pll_drdy = 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() - pll_drdy = Signal() - self.sync += If(self._pll_read.re | self._pll_write.re, - self._pll_drdy.status.eq(0) - ).Elif(pll_drdy, - self._pll_drdy.status.eq(1) - ) - self.specials += Instance("PLL_ADV", - p_CLKFBOUT_MULT=10, - p_CLKOUT0_DIVIDE=1, # pix10x - p_CLKOUT1_DIVIDE=5, # pix2x - p_CLKOUT2_DIVIDE=10, # pix - p_COMPENSATION="INTERNAL", - - i_CLKINSEL=1, - i_CLKIN1=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._pll_reset.storage, - - i_DADDR=self._pll_adr.storage, - o_DO=self._pll_dat_r.status, - i_DI=self._pll_dat_w.storage, - i_DEN=self._pll_read.re | self._pll_write.re, - i_DWE=self._pll_write.re, - o_DRDY=pll_drdy, - i_DCLK=ClockSignal()) - - 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._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/litex/soc/misoc/cores/dvi_sampler/common.py b/litex/soc/misoc/cores/dvi_sampler/common.py deleted file mode 100644 index 7fb9a420..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/common.py +++ /dev/null @@ -1,2 +0,0 @@ -control_tokens = [0b1101010100, 0b0010101011, 0b0101010100, 0b1010101011] -channel_layout = [("d", 8), ("c", 2), ("de", 1)] diff --git a/litex/soc/misoc/cores/dvi_sampler/core.py b/litex/soc/misoc/cores/dvi_sampler/core.py deleted file mode 100644 index f58e0d54..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/core.py +++ /dev/null @@ -1,80 +0,0 @@ -from migen import * - -from misoc.interconnect.csr import AutoCSR -from misoc.cores.dvi_sampler.edid import EDID -from misoc.cores.dvi_sampler.clocking import Clocking -from misoc.cores.dvi_sampler.datacapture import DataCapture -from misoc.cores.dvi_sampler.charsync import CharSync -from misoc.cores.dvi_sampler.wer import WER -from misoc.cores.dvi_sampler.decoding import Decoding -from misoc.cores.dvi_sampler.chansync import ChanSync -from misoc.cores.dvi_sampler.analysis import SyncPolarity, ResolutionDetection, FrameExtraction -from misoc.cores.dvi_sampler.dma import DMA - - -class DVISampler(Module, AutoCSR): - def __init__(self, pads, lasmim, n_dma_slots=2, fifo_depth=512): - 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(24*lasmim.dw//32, fifo_depth) - 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(lasmim, n_dma_slots) - self.comb += self.frame.frame.connect(self.dma.frame) - self.ev = self.dma.ev - - autocsr_exclude = {"ev"} diff --git a/litex/soc/misoc/cores/dvi_sampler/datacapture.py b/litex/soc/misoc/cores/dvi_sampler/datacapture.py deleted file mode 100644 index c1de9efe..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/datacapture.py +++ /dev/null @@ -1,188 +0,0 @@ -from migen import * -from migen.genlib.cdc import MultiReg, PulseSynchronizer - -from misoc.interconnect.csr import * - - -class DataCapture(Module, AutoCSR): - def __init__(self, pad_p, pad_n, ntbits): - self.serdesstrobe = Signal() - self.d = Signal(10) - - self._dly_ctl = CSR(6) - self._dly_busy = CSRStatus(2) - self._phase = CSRStatus(2) - self._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._dly_ctl.re & self._dly_ctl.r[0]), - self.do_delay_master_rst.i.eq(self._dly_ctl.re & self._dly_ctl.r[1]), - self.do_delay_slave_cal.i.eq(self._dly_ctl.re & self._dly_ctl.r[2]), - self.do_delay_slave_rst.i.eq(self._dly_ctl.re & self._dly_ctl.r[3]), - self.do_delay_inc.i.eq(self._dly_ctl.re & self._dly_ctl.r[4]), - self.do_delay_dec.i.eq(self._dly_ctl.re & self._dly_ctl.r[5]), - self._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._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._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/litex/soc/misoc/cores/dvi_sampler/debug.py b/litex/soc/misoc/cores/dvi_sampler/debug.py deleted file mode 100644 index f52a8b36..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/debug.py +++ /dev/null @@ -1,49 +0,0 @@ -from migen import * -from migen.genlib.fifo import AsyncFIFO -from migen.bank.description import AutoCSR -from migen.actorlib import structuring, spi - -from misoc.cores.dvi_sampler.edid import EDID -from misoc.cores.dvi_sampler.clocking import Clocking -from misoc.cores.dvi_sampler.datacapture import DataCapture - -# TODO -#from misoc.mem.sdram.frontend import dma_lasmi - - -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.word.eq(fifo.dout), - self.packer.source.connect_flat(self.cast.sink), - self.cast.source.connect_flat(self.dma.data) - ] diff --git a/litex/soc/misoc/cores/dvi_sampler/decoding.py b/litex/soc/misoc/cores/dvi_sampler/decoding.py deleted file mode 100644 index 195fd33e..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/decoding.py +++ /dev/null @@ -1,25 +0,0 @@ -from migen import * -from migen.genlib.record import Record - -from misoc.cores.dvi_sampler.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/litex/soc/misoc/cores/dvi_sampler/dma.py b/litex/soc/misoc/cores/dvi_sampler/dma.py deleted file mode 100644 index 8feab006..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/dma.py +++ /dev/null @@ -1,146 +0,0 @@ -from migen import * -from migen.genlib.fsm import FSM, NextState - -from misoc.interconnect.csr import * -from misoc.interconnect.csr_eventmanager import * - -# TODO: rewrite dma_lasmi module -# TODO: use stream packets to resync DMA -#from misoc.mem.sdram.frontend import dma_lasmi - - -# 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_reached = Signal(addr_bits) - self.address_valid = Signal() - self.address_done = Signal() - - self._status = CSRStorage(2, write_from_dev=True) - self._address = CSRStorage(addr_bits + alignment_bits, alignment_bits=alignment_bits, write_from_dev=True) - - ### - - self.comb += [ - self.address.eq(self._address.storage), - self.address_valid.eq(self._status.storage[0]), - self._status.dat_w.eq(2), - self._status.we.eq(self.address_done), - self._address.dat_w.eq(self.address_reached), - self._address.we.eq(self.address_done), - self.ev_source.trigger.eq(self._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_reached = 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_reached.eq(self.address_reached) for slot in slots] - 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 - - fifo_word_width = 24*bus_dw//32 - self.frame = Sink([("sof", 1), ("pixels", fifo_word_width)]) - self._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 - - ### - - # 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 += [ - self._slot_array.address_reached.eq(current_address), - last_word.eq(mwords_remaining == 1) - ] - self.sync += [ - If(reset_words, - current_address.eq(self._slot_array.address), - mwords_remaining.eq(self._frame_size.storage) - ).Elif(count_word, - current_address.eq(current_address + 1), - mwords_remaining.eq(mwords_remaining - 1) - ) - ] - - # 24bpp -> 32bpp - memory_word = Signal(bus_dw) - pixbits = [] - for i in range(bus_dw//32): - for j in range(3): - b = (i*3+j)*8 - pixbits.append(self.frame.pixels[b+6:b+8]) - pixbits.append(self.frame.pixels[b:b+8]) - pixbits.append(0) - pixbits.append(0) - self.comb += memory_word.eq(Cat(*pixbits)) - - # bus accessor - self.submodules._bus_accessor = dma_lasmi.Writer(lasmim) - self.comb += [ - self._bus_accessor.address_data.a.eq(current_address), - self._bus_accessor.address_data.d.eq(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 | ~self.frame.sof), - If(self._slot_array.address_valid & self.frame.sof & self.frame.stb, NextState("TRANSFER_PIXELS")) - ) - fsm.act("TRANSFER_PIXELS", - self.frame.ack.eq(self._bus_accessor.address_data.ack), - If(self.frame.stb, - self._bus_accessor.address_data.stb.eq(1), - If(self._bus_accessor.address_data.ack, - count_word.eq(1), - If(last_word, NextState("EOF")) - ) - ) - ) - fsm.act("EOF", - If(~self._bus_accessor.busy, - self._slot_array.address_done.eq(1), - NextState("WAIT_SOF") - ) - ) - - def get_csrs(self): - return [self._frame_size] + self._slot_array.get_csrs() diff --git a/litex/soc/misoc/cores/dvi_sampler/edid.py b/litex/soc/misoc/cores/dvi_sampler/edid.py deleted file mode 100644 index a04e2361..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/edid.py +++ /dev/null @@ -1,196 +0,0 @@ -from migen 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 misoc.interconnect.csr 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._hpd_notif = CSRStatus() - self._hpd_en = CSRStorage() - self.specials.mem = Memory(8, 128, init=default) - - ### - - # HPD - if hasattr(pads, "hpd_notif"): - self.specials += MultiReg(pads.hpd_notif, self._hpd_notif.status) - else: - self.comb += self._hpd_notif.status.eq(1) - if hasattr(pads, "hpd_en"): - self.comb += pads.hpd_en.eq(self._hpd_en.storage) - - # EDID - scl_raw = Signal() - sda_i = Signal() - sda_raw = 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_raw) - ] - - 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), - sda_i.eq(sda_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._hpd_en.storage, NextState("WAIT_START"))) diff --git a/litex/soc/misoc/cores/dvi_sampler/wer.py b/litex/soc/misoc/cores/dvi_sampler/wer.py deleted file mode 100644 index 0bcd02ec..00000000 --- a/litex/soc/misoc/cores/dvi_sampler/wer.py +++ /dev/null @@ -1,62 +0,0 @@ -from functools import reduce -from operator import add, or_ - -from migen import * -from migen.genlib.cdc import PulseSynchronizer - -from misoc.interconnect.csr import * -from misoc.cores.dvi_sampler.common import control_tokens - - -class WER(Module, AutoCSR): - def __init__(self, period_bits=24): - self.data = Signal(10) - self._update = CSR() - self._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(reduce(add, [transitions[i] for i in range(8)])) - - is_control = Signal() - self.sync.pix += is_control.eq(reduce(or_, [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._update.re, self._value.status.eq(wer_counter_sys)) diff --git a/litex/soc/misoc/cores/framebuffer/__init__.py b/litex/soc/misoc/cores/framebuffer/__init__.py deleted file mode 100644 index 24051495..00000000 --- a/litex/soc/misoc/cores/framebuffer/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.framebuffer.core import Framebuffer diff --git a/litex/soc/misoc/cores/framebuffer/core.py b/litex/soc/misoc/cores/framebuffer/core.py deleted file mode 100644 index fc7ce067..00000000 --- a/litex/soc/misoc/cores/framebuffer/core.py +++ /dev/null @@ -1,33 +0,0 @@ -from migen import * -from migen.flow.network import * -from migen.flow import plumbing -from migen.bank.description import AutoCSR -from migen.actorlib import structuring, misc - -from misoc.mem.sdram.frontend import dma_lasmi -from misoc.framebuffer.format import bpp, pixel_layout, FrameInitiator, VTG -from misoc.framebuffer.phy import Driver - - -class Framebuffer(Module, AutoCSR): - def __init__(self, pads_vga, pads_dvi, lasmim): - pack_factor = lasmim.dw//bpp - - g = DataFlowGraph() - - self.fi = FrameInitiator(lasmim.aw, pack_factor) - - intseq = misc.IntSequence(lasmim.aw, lasmim.aw) - dma_out = AbstractActor(plumbing.Buffer) - g.add_connection(self.fi, intseq, source_subr=self.fi.dma_subr()) - g.add_pipeline(intseq, AbstractActor(plumbing.Buffer), dma_lasmi.Reader(lasmim), dma_out) - - cast = structuring.Cast(lasmim.dw, pixel_layout(pack_factor), reverse_to=True) - vtg = VTG(pack_factor) - self.driver = Driver(pack_factor, pads_vga, pads_dvi) - - g.add_connection(self.fi, vtg, source_subr=self.fi.timing_subr, sink_ep="timing") - g.add_connection(dma_out, cast) - g.add_connection(cast, vtg, sink_ep="pixels") - g.add_connection(vtg, self.driver) - self.submodules += CompositeActor(g) diff --git a/litex/soc/misoc/cores/framebuffer/dvi.py b/litex/soc/misoc/cores/framebuffer/dvi.py deleted file mode 100644 index e24e7fed..00000000 --- a/litex/soc/misoc/cores/framebuffer/dvi.py +++ /dev/null @@ -1,227 +0,0 @@ -from functools import reduce -from operator import add - -from migen import * - - -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(reduce(add, [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(reduce(add, [~q_m[i] for i in range(8)])), - n1q_m.eq(reduce(add, [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, selfp): - if self._end_cycle is None: - try: - nv = next(self._iter_inputs) - except StopIteration: - self._end_cycle = selfp.simulator.cycle_counter + 4 - else: - selfp.dut.d = nv - if selfp.simulator.cycle_counter == self._end_cycle: - raise StopSimulation - if selfp.simulator.cycle_counter > 4: - self.outs.append(selfp.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 run_simulation - from random import Random - - rng = Random(788) - test_list = [rng.randrange(256) for i in range(500)] - tb = _EncoderTB(test_list) - run_simulation(tb) - - 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/litex/soc/misoc/cores/framebuffer/format.py b/litex/soc/misoc/cores/framebuffer/format.py deleted file mode 100644 index 210ec5ce..00000000 --- a/litex/soc/misoc/cores/framebuffer/format.py +++ /dev/null @@ -1,150 +0,0 @@ -from migen import * -from migen.flow.actor import * -from migen.bank.description import CSRStorage -from migen.genlib.record import Record -from migen.genlib.fsm import FSM, NextState -from migen.actorlib import spi - -_hbits = 12 -_vbits = 12 - -bpp = 32 -bpc = 10 -pixel_layout_s = [ - ("pad", bpp-3*bpc), - ("r", bpc), - ("g", bpc), - ("b", bpc) -] - - -def pixel_layout(pack_factor): - return [("p"+str(i), pixel_layout_s) for i in range(pack_factor)] - -bpc_phy = 8 -phy_layout_s = [ - ("r", bpc_phy), - ("g", bpc_phy), - ("b", bpc_phy) -] - - -def phy_layout(pack_factor): - r = [("hsync", 1), ("vsync", 1), ("de", 1)] - for i in range(pack_factor): - r.append(("p"+str(i), phy_layout_s)) - return r - - -class FrameInitiator(spi.SingleGenerator): - def __init__(self, bus_aw, pack_factor, ndmas=1): - h_alignment_bits = log2_int(pack_factor) - hbits_dyn = _hbits - h_alignment_bits - bus_alignment_bits = h_alignment_bits + log2_int(bpp//8) - layout = [ - ("hres", hbits_dyn, 640, h_alignment_bits), - ("hsync_start", hbits_dyn, 656, h_alignment_bits), - ("hsync_end", hbits_dyn, 752, h_alignment_bits), - ("hscan", hbits_dyn, 800, h_alignment_bits), - - ("vres", _vbits, 480), - ("vsync_start", _vbits, 492), - ("vsync_end", _vbits, 494), - ("vscan", _vbits, 525), - - ("length", bus_aw + bus_alignment_bits, 640*480*bpp//8, bus_alignment_bits) - ] - layout += [("base"+str(i), bus_aw + bus_alignment_bits, 0, bus_alignment_bits) - for i in range(ndmas)] - spi.SingleGenerator.__init__(self, layout, spi.MODE_CONTINUOUS) - - timing_subr = ["hres", "hsync_start", "hsync_end", "hscan", - "vres", "vsync_start", "vsync_end", "vscan"] - - def dma_subr(self, i=0): - return ["length", "base"+str(i)] - - -class VTG(Module): - def __init__(self, pack_factor): - hbits_dyn = _hbits - log2_int(pack_factor) - timing_layout = [ - ("hres", hbits_dyn), - ("hsync_start", hbits_dyn), - ("hsync_end", hbits_dyn), - ("hscan", hbits_dyn), - ("vres", _vbits), - ("vsync_start", _vbits), - ("vsync_end", _vbits), - ("vscan", _vbits)] - self.timing = Sink(timing_layout) - self.pixels = Sink(pixel_layout(pack_factor)) - self.phy = Source(phy_layout(pack_factor)) - self.busy = Signal() - - ### - - hactive = Signal() - vactive = Signal() - active = Signal() - - hcounter = Signal(hbits_dyn) - 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 ["p"+str(i) for i in range(pack_factor)] for c in ["r", "g", "b"]], - self.phy.de.eq(1) - ), - self.pixels.ack.eq(self.phy.ack & active) - ] - - load_timing = Signal() - tr = Record(timing_layout) - self.sync += If(load_timing, tr.eq(self.timing.payload)) - - generate_en = Signal() - generate_frame_done = Signal() - self.sync += [ - generate_frame_done.eq(0), - If(generate_en, - hcounter.eq(hcounter + 1), - - If(hcounter == 0, hactive.eq(1)), - If(hcounter == tr.hres, hactive.eq(0)), - If(hcounter == tr.hsync_start, self.phy.hsync.eq(1)), - If(hcounter == tr.hsync_end, self.phy.hsync.eq(0)), - If(hcounter == tr.hscan, - hcounter.eq(0), - If(vcounter == tr.vscan, - vcounter.eq(0), - generate_frame_done.eq(1) - ).Else( - vcounter.eq(vcounter + 1) - ) - ), - - If(vcounter == 0, vactive.eq(1)), - If(vcounter == tr.vres, vactive.eq(0)), - If(vcounter == tr.vsync_start, self.phy.vsync.eq(1)), - If(vcounter == tr.vsync_end, self.phy.vsync.eq(0)) - ) - ] - - self.submodules.fsm = FSM() - self.fsm.act("GET_TIMING", - self.timing.ack.eq(1), - load_timing.eq(1), - If(self.timing.stb, NextState("GENERATE")) - ) - self.fsm.act("GENERATE", - self.busy.eq(1), - If(~active | self.pixels.stb, - self.phy.stb.eq(1), - If(self.phy.ack, generate_en.eq(1)) - ), - If(generate_frame_done, NextState("GET_TIMING")) - ) diff --git a/litex/soc/misoc/cores/framebuffer/phy.py b/litex/soc/misoc/cores/framebuffer/phy.py deleted file mode 100644 index 497c861e..00000000 --- a/litex/soc/misoc/cores/framebuffer/phy.py +++ /dev/null @@ -1,222 +0,0 @@ -from migen import * -from migen.genlib.fifo import AsyncFIFO -from migen.genlib.cdc import MultiReg -from migen.bank.description import * -from migen.flow.actor import * - -from misoc.framebuffer.format import bpc_phy, phy_layout -from misoc.framebuffer import dvi - - -class _FIFO(Module): - def __init__(self, pack_factor): - self.phy = Sink(phy_layout(pack_factor)) - 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(pack_factor), 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) - ] - - unpack_counter = Signal(max=pack_factor) - assert(pack_factor & (pack_factor - 1) == 0) # only support powers of 2 - self.sync.pix += [ - unpack_counter.eq(unpack_counter + 1), - self.pix_hsync.eq(fifo.dout.hsync), - self.pix_vsync.eq(fifo.dout.vsync), - self.pix_de.eq(fifo.dout.de) - ] - for i in range(pack_factor): - pixel = getattr(fifo.dout, "p"+str(i)) - self.sync.pix += If(unpack_counter == i, - self.pix_r.eq(pixel.r), - self.pix_g.eq(pixel.g), - self.pix_b.eq(pixel.b) - ) - self.comb += fifo.re.eq(unpack_counter == (pack_factor - 1)) - - -# This assumes a 50MHz base clock -class _Clocking(Module, AutoCSR): - def __init__(self, pads_vga, pads_dvi): - self._cmd_data = CSRStorage(10) - self._send_cmd_data = CSR() - self._send_go = CSR() - self._status = CSRStatus(4) - - self.clock_domains.cd_pix = ClockDomain(reset_less=True) - if pads_dvi is not None: - self._pll_reset = CSRStorage() - self._pll_adr = CSRStorage(5) - self._pll_dat_r = CSRStatus(16) - self._pll_dat_w = CSRStorage(16) - self._pll_read = CSR() - self._pll_write = CSR() - self._pll_drdy = CSRStatus() - - 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._send_cmd_data.re, - remaining_bits.eq(10), - sr.eq(self._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._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._send_cmd_data.re, - busy_counter.eq(13) - ).Elif(busy, - busy_counter.eq(busy_counter - 1) - ) - - mult_locked = Signal() - self.comb += self._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() - pll_drdy = Signal() - self.sync += If(self._pll_read.re | self._pll_write.re, - self._pll_drdy.status.eq(0) - ).Elif(pll_drdy, - self._pll_drdy.status.eq(1) - ) - self.specials += [ - Instance("PLL_ADV", - p_CLKFBOUT_MULT=10, - p_CLKOUT0_DIVIDE=1, # pix10x - p_CLKOUT1_DIVIDE=5, # pix2x - p_CLKOUT2_DIVIDE=10, # pix - p_COMPENSATION="INTERNAL", - - i_CLKINSEL=1, - i_CLKIN1=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 | self._pll_reset.storage, - - i_DADDR=self._pll_adr.storage, - o_DO=self._pll_dat_r.status, - i_DI=self._pll_dat_w.storage, - i_DEN=self._pll_read.re | self._pll_write.re, - i_DWE=self._pll_write.re, - o_DRDY=pll_drdy, - i_DCLK=ClockSignal()), - 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, pack_factor, pads_vga, pads_dvi): - fifo = _FIFO(pack_factor) - 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/litex/soc/misoc/cores/lasmicon/__init__.py b/litex/soc/misoc/cores/lasmicon/__init__.py deleted file mode 100644 index a66d8c04..00000000 --- a/litex/soc/misoc/cores/lasmicon/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.lasmicon.core import ControllerSettings, LASMIcon diff --git a/litex/soc/misoc/cores/lasmicon/test_bankmachine.py b/litex/soc/misoc/cores/lasmicon/test_bankmachine.py deleted file mode 100644 index f6f03405..00000000 --- a/litex/soc/misoc/cores/lasmicon/test_bankmachine.py +++ /dev/null @@ -1,43 +0,0 @@ -from migen import * -from migen.sim.generic import run_simulation - -from misoc.mem.sdram.code import lasmibus -from misoc.mem.sdram.core.lasmicon.bankmachine import * - -from test_common import sdram_phy, sdram_geom, sdram_timing, CommandLogger - - -def my_generator(): - for x in range(10): - yield True, x - for x in range(10): - yield False, 128*x - - -class TB(Module): - def __init__(self): - self.req = Interface(32, 32, 1, - sdram_timing.req_queue_size, sdram_phy.read_latency, sdram_phy.write_latency) - self.submodules.dut = BankMachine(sdram_geom, sdram_timing, 2, 0, self.req) - self.submodules.logger = CommandLogger(self.dut.cmd, True) - self.generator = my_generator() - self.dat_ack_cnt = 0 - - def do_simulation(self, selfp): - if selfp.req.dat_ack: - self.dat_ack_cnt += 1 - if selfp.req.req_ack: - try: - we, adr = next(self.generator) - except StopIteration: - selfp.req.stb = 0 - if not selfp.req.lock: - print("data ack count: {0}".format(self.dat_ack_cnt)) - raise StopSimulation - return - selfp.req.adr = adr - selfp.req.we = we - selfp.req.stb = 1 - -if __name__ == "__main__": - run_simulation(TB(), vcd_name="my.vcd") diff --git a/litex/soc/misoc/cores/lasmicon/test_common.py b/litex/soc/misoc/cores/lasmicon/test_common.py deleted file mode 100644 index 8a537484..00000000 --- a/litex/soc/misoc/cores/lasmicon/test_common.py +++ /dev/null @@ -1,106 +0,0 @@ -from fractions import Fraction -from math import ceil - -from migen import * - -from misoc import sdram - -MHz = 1000000 -clk_freq = (83 + Fraction(1, 3))*MHz - -clk_period_ns = 1000000000/clk_freq - - -def ns(t, margin=True): - if margin: - t += clk_period_ns/2 - return ceil(t/clk_period_ns) - -sdram_phy = sdram.PhySettings( - memtype="DDR", - dfi_databits=64, - nphases=2, - rdphase=0, - wrphase=1, - rdcmdphase=1, - wrcmdphase=0, - cl=3, - read_latency=5, - write_latency=0 -) - -sdram_geom = sdram.GeomSettings( - bankbits=2, - rowbits=13, - colbits=10 -) -sdram_timing = sdram.TimingSettings( - tRP=ns(15), - tRCD=ns(15), - tWR=ns(15), - tWTR=2, - tREFI=ns(7800, False), - tRFC=ns(70), - - req_queue_size=8, - read_time=32, - write_time=16 -) - - -def decode_sdram(ras_n, cas_n, we_n, bank, address): - elts = [] - if not ras_n and cas_n and we_n: - elts.append("ACTIVATE") - elts.append("BANK " + str(bank)) - elts.append("ROW " + str(address)) - elif ras_n and not cas_n and we_n: - elts.append("READ\t") - elts.append("BANK " + str(bank)) - elts.append("COL " + str(address)) - elif ras_n and not cas_n and not we_n: - elts.append("WRITE\t") - elts.append("BANK " + str(bank)) - elts.append("COL " + str(address)) - elif ras_n and cas_n and not we_n: - elts.append("BST") - elif not ras_n and not cas_n and we_n: - elts.append("AUTO REFRESH") - elif not ras_n and cas_n and not we_n: - elts.append("PRECHARGE") - if address & 2**10: - elts.append("ALL") - else: - elts.append("BANK " + str(bank)) - elif not ras_n and not cas_n and not we_n: - elts.append("LMR") - return elts - - -class CommandLogger(Module): - def __init__(self, cmd, rw=False): - self.cmd = cmd - if rw: - self.comb += self.cmd.ack.eq(1) - - def do_simulation(self, selfp): - elts = ["@" + str(selfp.simulator.cycle_counter)] - cmdp = selfp.cmd - elts += decode_sdram(cmdp.ras_n, cmdp.cas_n, cmdp.we_n, cmdp.ba, cmdp.a) - if len(elts) > 1: - print("\t".join(elts)) - do_simulation.passive = True - - -class DFILogger(Module): - def __init__(self, dfi): - self.dfi = dfi - - def do_simulation(self, selfp): - dfip = selfp.dfi - for i, p in enumerate(dfip.phases): - elts = ["@" + str(selfp.simulator.cycle_counter) + ":" + str(i)] - elts += decode_sdram(p.ras_n, p.cas_n, p.we_n, p.bank, p.address) - if len(elts) > 1: - print("\t".join(elts)) - do_simulation.passive = True diff --git a/litex/soc/misoc/cores/lasmicon/test_df.py b/litex/soc/misoc/cores/lasmicon/test_df.py deleted file mode 100644 index 588bd67f..00000000 --- a/litex/soc/misoc/cores/lasmicon/test_df.py +++ /dev/null @@ -1,40 +0,0 @@ -from migen import * -from migen.sim.generic import run_simulation - -from misoc.mem.sdram.core import lasmibus -from misoc.mem.sdram.core.lasmicon import * -from misoc.mem.sdram.frontend import dma_lasmi - -from test_common import sdram_phy, sdram_geom, sdram_timing, DFILogger - - -class TB(Module): - def __init__(self): - self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing) - self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits) - self.submodules.logger = DFILogger(self.ctler.dfi) - self.submodules.writer = dma_lasmi.Writer(self.xbar.get_master()) - - self.comb += self.writer.address_data.stb.eq(1) - pl = self.writer.address_data.payload - pl.a.reset = 255 - pl.d.reset = pl.a.reset*2 - self.sync += If(self.writer.address_data.ack, - pl.a.eq(pl.a + 1), - pl.d.eq(pl.d + 2) - ) - self.open_row = None - - def do_simulation(self, selfp): - dfip = selfp.ctler.dfi - for p in dfip.phases: - if p.ras_n and not p.cas_n and not p.we_n: # write - d = dfip.phases[0].wrdata | (dfip.phases[1].wrdata << 64) - print(d) - if d != p.address//2 + p.bank*512 + self.open_row*2048: - print("**** ERROR ****") - elif not p.ras_n and p.cas_n and p.we_n: # activate - self.open_row = p.address - -if __name__ == "__main__": - run_simulation(TB(), ncycles=3500, vcd_name="my.vcd") diff --git a/litex/soc/misoc/cores/lasmicon/test_lasmi.py b/litex/soc/misoc/cores/lasmicon/test_lasmi.py deleted file mode 100644 index b81f14db..00000000 --- a/litex/soc/misoc/cores/lasmicon/test_lasmi.py +++ /dev/null @@ -1,43 +0,0 @@ -from migen import * -from migen.sim.generic import run_simulation - -from misoc.mem.sdram.core import lasmibus -from misoc.mem.sdram.core.lasmicon import * - -from test_common import sdram_phy, sdram_geom, sdram_timing, DFILogger - - -def my_generator_r(n): - for x in range(10): - t = TRead(128*n + 48*n*x) - yield t - print("{0:3}: reads done".format(n)) - - -def my_generator_w(n): - for x in range(10): - t = TWrite(128*n + 48*n*x, x) - yield t - print("{0:3}: writes done".format(n)) - - -def my_generator(n): - if n % 2: - return my_generator_w(n // 2) - else: - return my_generator_r(n // 2) - - -class TB(Module): - def __init__(self): - self.submodules.dut = LASMIcon(sdram_phy, sdram_geom, sdram_timing) - self.submodules.xbar = lasmibus.Crossbar([self.dut.lasmic], self.dut.nrowbits) - self.submodules.logger = DFILogger(self.dut.dfi) - - masters = [self.xbar.get_master() for i in range(6)] - self.initiators = [Initiator(my_generator(n), master) - for n, master in enumerate(masters)] - self.submodules += self.initiators - -if __name__ == "__main__": - run_simulation(TB(), vcd_name="my.vcd") diff --git a/litex/soc/misoc/cores/lasmicon/test_refresher.py b/litex/soc/misoc/cores/lasmicon/test_refresher.py deleted file mode 100644 index 5722b09d..00000000 --- a/litex/soc/misoc/cores/lasmicon/test_refresher.py +++ /dev/null @@ -1,47 +0,0 @@ -from random import Random - -from migen import * -from migen.sim.generic import run_simulation - -from misoc.mem.sdram.core.lasmicon.refresher import * - -from common import CommandLogger - - -class Granter(Module): - def __init__(self, req, ack): - self.req = req - self.ack = ack - self.state = 0 - self.prng = Random(92837) - - def do_simulation(self, selfp): - elts = ["@" + str(selfp.simulator.cycle_counter)] - - if self.state == 0: - if selfp.req: - elts.append("Refresher requested access") - self.state = 1 - elif self.state == 1: - if self.prng.randrange(0, 5) == 0: - elts.append("Granted access to refresher") - selfp.ack = 1 - self.state = 2 - elif self.state == 2: - if not selfp.req: - elts.append("Refresher released access") - selfp.ack = 0 - self.state = 0 - - if len(elts) > 1: - print("\t".join(elts)) - - -class TB(Module): - def __init__(self): - self.submodules.dut = Refresher(13, 2, tRP=3, tREFI=100, tRFC=5) - self.submodules.logger = CommandLogger(self.dut.cmd) - self.submodules.granter = Granter(self.dut.req, self.dut.ack) - -if __name__ == "__main__": - run_simulation(TB(), ncycles=400) diff --git a/litex/soc/misoc/cores/lasmicon/test_wb.py b/litex/soc/misoc/cores/lasmicon/test_wb.py deleted file mode 100644 index abbaed9a..00000000 --- a/litex/soc/misoc/cores/lasmicon/test_wb.py +++ /dev/null @@ -1,40 +0,0 @@ -from migen import * -from migen.bus import wishbone -from migen.bus.transactions import * -from migen.sim.generic import run_simulation - -from misoc.mem.sdram.core import lasmibus -from misoc.mem.sdram.core.lasmicon import * -from misoc.mem.sdram.frontend import wishbone2lasmi - -from test_common import sdram_phy, sdram_geom, sdram_timing, DFILogger - -l2_size = 8192 # in bytes - - -def my_generator(): - for x in range(20): - t = TWrite(x, x) - yield t - print(str(t) + " delay=" + str(t.latency)) - for x in range(20): - t = TRead(x) - yield t - print(str(t) + " delay=" + str(t.latency)) - for x in range(20): - t = TRead(x+l2_size//4) - yield t - print(str(t) + " delay=" + str(t.latency)) - - -class TB(Module): - def __init__(self): - self.submodules.ctler = LASMIcon(sdram_phy, sdram_geom, sdram_timing) - self.submodules.xbar = lasmibus.Crossbar([self.ctler.lasmic], self.ctler.nrowbits) - self.submodules.logger = DFILogger(self.ctler.dfi) - self.submodules.bridge = wishbone2lasmi.WB2LASMI(l2_size//4, self.xbar.get_master()) - self.submodules.initiator = wishbone.Initiator(my_generator()) - self.submodules.conn = wishbone.InterconnectPointToPoint(self.initiator.bus, self.bridge.wishbone) - -if __name__ == "__main__": - run_simulation(TB(), vcd_name="my.vcd") diff --git a/litex/soc/misoc/cores/liteeth_mini/LICENSE b/litex/soc/misoc/cores/liteeth_mini/LICENSE deleted file mode 100644 index cbbfe8be..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/LICENSE +++ /dev/null @@ -1,28 +0,0 @@ -Unless otherwise noted, LiteEth is copyright (C) 2015 Florent Kermarrec. - -Redistribution and use in source and binary forms, with or without modification, -are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND -ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED -WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR -ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES -(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; -LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON -ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - - -Other authors retain ownership of their contributions. If a submission can -reasonably be considered independently copyrightable, it's yours and we -encourage you to claim it with appropriate copyright notices. This submission -then falls under the "otherwise noted" category. All submissions are strongly -encouraged to use the two-clause BSD license reproduced above. diff --git a/litex/soc/misoc/cores/liteeth_mini/README b/litex/soc/misoc/cores/liteeth_mini/README deleted file mode 100644 index 595d2fc9..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/README +++ /dev/null @@ -1,58 +0,0 @@ - __ _ __ ______ __ __ ____ _ - / / (_) /____ / __/ /_/ / / |/ (_)__ (_) - / /__/ / __/ -_) _// __/ _ \/ /|_/ / / _ \/ / - /____/_/\__/\__/___/\__/_//_/_/ /_/_/_//_/_/ - - Copyright 2012-2015 / EnjoyDigital / M-Labs Ltd - - A small footprint and configurable minimal Ethernet core - powered by Migen - -[> Intro ---------- -LiteEthMini is a subset of LiteEth (https://github.com/enjoy-digital/liteeth) -intended to be used with a CPU and a software stack. - -[> Features ------------ -- Ethernet MAC with various various PHYs (GMII, MII, RGMII, Loopback) -- SRAM storage and wishbone interface - -[> Possible improvements -------------------------- -- add DMA interface to MAC -- add SGMII PHY -- ... See below Support and consulting :) - -If you want to support these features, please contact us at florent [AT] -enjoy-digital.fr. You can also contact our partner on the public mailing list -devel [AT] lists.m-labs.hk. - -[> License ------------ -LiteEthMini is released under the very permissive two-clause BSD license. Under -the terms of this license, you are authorized to use LiteEthMini 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 LiteEthMini - - cite LiteEthMini 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 LiteEthMini. - -[> Support and consulting --------------------------- -We love open-source hardware and like sharing our designs with others. - -LiteEthMini is mainly developed and maintained by EnjoyDigital. - -If you would like to know more about LiteEthMini or if you are already a happy -user and would like to extend it for your needs, EnjoyDigital can provide standard -commercial support as well as consulting services. - -So feel free to contact us, we'd love to work with you! (and eventually shorten -the list of the possible improvements :) - -[> Contact -E-mail: florent [AT] enjoy-digital.fr \ No newline at end of file diff --git a/litex/soc/misoc/cores/liteeth_mini/common.py b/litex/soc/misoc/cores/liteeth_mini/common.py deleted file mode 100644 index 4638c76c..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/common.py +++ /dev/null @@ -1,38 +0,0 @@ -from migen import * -from migen.genlib.record import * - -from misoc.interconnect.csr import * -from misoc.interconnect.stream import * - - -class Port: - def connect(self, port): - r = [ - Record.connect(self.source, port.sink), - Record.connect(port.source, self.sink) - ] - return r - -eth_mtu = 1532 -eth_min_len = 46 -eth_interpacket_gap = 12 -eth_preamble = 0xD555555555555555 -buffer_depth = 2**log2_int(eth_mtu, need_pow2=False) - - -def eth_phy_description(dw): - payload_layout = [ - ("data", dw), - ("last_be", dw//8), - ("error", dw//8) - ] - return EndpointDescription(payload_layout, packetized=True) - - -def eth_mac_description(dw): - payload_layout = mac_header.get_layout() + [ - ("data", dw), - ("last_be", dw//8), - ("error", dw//8) - ] - return EndpointDescription(payload_layout, packetized=True) diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/__init__.py b/litex/soc/misoc/cores/liteeth_mini/mac/__init__.py deleted file mode 100644 index d821ca69..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/__init__.py +++ /dev/null @@ -1,25 +0,0 @@ -from migen import * - -from misoc.interconnect.csr import * -from misoc.cores.liteeth_mini.common import * -from misoc.cores.liteeth_mini.mac.core import LiteEthMACCore -from misoc.cores.liteeth_mini.mac.frontend.wishbone import LiteEthMACWishboneInterface - - -class LiteEthMAC(Module, AutoCSR): - def __init__(self, phy, dw, - interface="wishbone", - endianness="big", - with_preamble_crc=True): - self.submodules.core = LiteEthMACCore(phy, dw, endianness, with_preamble_crc) - self.csrs = [] - if interface == "wishbone": - self.submodules.interface = LiteEthMACWishboneInterface(dw, 2, 2) - self.comb += Port.connect(self.interface, self.core) - self.ev, self.bus = self.interface.sram.ev, self.interface.bus - self.csrs = self.interface.get_csrs() + self.core.get_csrs() - else: - raise NotImplementedError - - def get_csrs(self): - return self.csrs diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/core/__init__.py b/litex/soc/misoc/cores/liteeth_mini/mac/core/__init__.py deleted file mode 100644 index c8badcd7..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/core/__init__.py +++ /dev/null @@ -1,100 +0,0 @@ -from migen import * - -from misoc.interconnect.csr import * -from misoc.cores.liteeth_mini.common import * -from misoc.cores.liteeth_mini.mac.core import gap, preamble, crc, padding, last_be -from misoc.cores.liteeth_mini.phy.mii import LiteEthPHYMII - - -class LiteEthMACCore(Module, AutoCSR): - def __init__(self, phy, dw, endianness="big", - with_preamble_crc=True, - with_padding=True): - if dw < phy.dw: - raise ValueError("Core data width({}) must be larger than PHY data width({})".format(dw, phy.dw)) - - rx_pipeline = [phy] - tx_pipeline = [phy] - - # Interpacket gap - tx_gap_inserter = gap.LiteEthMACGap(phy.dw) - rx_gap_checker = gap.LiteEthMACGap(phy.dw, ack_on_gap=True) - self.submodules += ClockDomainsRenamer("eth_tx")(tx_gap_inserter) - self.submodules += ClockDomainsRenamer("eth_rx")(rx_gap_checker) - - tx_pipeline += [tx_gap_inserter] - rx_pipeline += [rx_gap_checker] - - # Preamble / CRC - if with_preamble_crc: - self._preamble_crc = CSRStatus(reset=1) - # Preamble insert/check - preamble_inserter = preamble.LiteEthMACPreambleInserter(phy.dw) - preamble_checker = preamble.LiteEthMACPreambleChecker(phy.dw) - self.submodules += ClockDomainsRenamer("eth_tx")(preamble_inserter) - self.submodules += ClockDomainsRenamer("eth_rx")(preamble_checker) - - # CRC insert/check - crc32_inserter = crc.LiteEthMACCRC32Inserter(eth_phy_description(phy.dw)) - crc32_checker = crc.LiteEthMACCRC32Checker(eth_phy_description(phy.dw)) - self.submodules += ClockDomainsRenamer("eth_tx")(crc32_inserter) - self.submodules += ClockDomainsRenamer("eth_rx")(crc32_checker) - - tx_pipeline += [preamble_inserter, crc32_inserter] - rx_pipeline += [preamble_checker, crc32_checker] - - # Padding - if with_padding: - padding_inserter = padding.LiteEthMACPaddingInserter(phy.dw, 60) - padding_checker = padding.LiteEthMACPaddingChecker(phy.dw, 60) - self.submodules += ClockDomainsRenamer("eth_tx")(padding_inserter) - self.submodules += ClockDomainsRenamer("eth_rx")(padding_checker) - - tx_pipeline += [padding_inserter] - rx_pipeline += [padding_checker] - - # Delimiters - if dw != 8: - tx_last_be = last_be.LiteEthMACTXLastBE(phy.dw) - rx_last_be = last_be.LiteEthMACRXLastBE(phy.dw) - self.submodules += ClockDomainsRenamer("eth_tx")(tx_last_be) - self.submodules += ClockDomainsRenamer("eth_rx")(rx_last_be) - - tx_pipeline += [tx_last_be] - rx_pipeline += [rx_last_be] - - # Converters - if dw != phy.dw: - reverse = endianness == "big" - tx_converter = Converter(eth_phy_description(dw), - eth_phy_description(phy.dw), - reverse=reverse) - rx_converter = Converter(eth_phy_description(phy.dw), - eth_phy_description(dw), - reverse=reverse) - self.submodules += ClockDomainsRenamer("eth_tx")(tx_converter) - self.submodules += ClockDomainsRenamer("eth_rx")(rx_converter) - - tx_pipeline += [tx_converter] - rx_pipeline += [rx_converter] - - # Cross Domain Crossing - if isinstance(phy, LiteEthPHYMII): - fifo_depth = 8 - else: - fifo_depth = 64 - tx_cdc = AsyncFIFO(eth_phy_description(dw), fifo_depth) - rx_cdc = AsyncFIFO(eth_phy_description(dw), fifo_depth) - self.submodules += ClockDomainsRenamer({"write": "sys", "read": "eth_tx"})(tx_cdc) - self.submodules += ClockDomainsRenamer({"write": "eth_rx", "read": "sys"})(rx_cdc) - - tx_pipeline += [tx_cdc] - rx_pipeline += [rx_cdc] - - tx_pipeline_r = list(reversed(tx_pipeline)) - for s, d in zip(tx_pipeline_r, tx_pipeline_r[1:]): - self.comb += s.source.connect(d.sink) - for s, d in zip(rx_pipeline, rx_pipeline[1:]): - self.comb += s.source.connect(d.sink) - self.sink = tx_pipeline[-1].sink - self.source = rx_pipeline[-1].source diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/core/crc.py b/litex/soc/misoc/cores/liteeth_mini/mac/core/crc.py deleted file mode 100644 index 0052f321..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/core/crc.py +++ /dev/null @@ -1,287 +0,0 @@ -from collections import OrderedDict -from functools import reduce -from operator import xor - -from migen import * -from migen.genlib.misc import chooser - -from misoc.interconnect.stream import * - - -class LiteEthMACCRCEngine(Module): - """Cyclic Redundancy Check Engine - - Compute next CRC value from last CRC value and data input using - an optimized asynchronous LFSR. - - Parameters - ---------- - data_width : int - Width of the data bus. - width : int - Width of the CRC. - polynom : int - Polynom of the CRC (ex: 0x04C11DB7 for IEEE 802.3 CRC) - - Attributes - ---------- - data : in - Data input. - last : in - last CRC value. - next : - next CRC value. - """ - def __init__(self, data_width, width, polynom): - self.data = Signal(data_width) - self.last = Signal(width) - self.next = Signal(width) - - # # # - - def _optimize_eq(l): - """ - Replace even numbers of XORs in the equation - with an equivalent XOR - """ - d = OrderedDict() - for e in l: - if e in d: - d[e] += 1 - else: - d[e] = 1 - r = [] - for key, value in d.items(): - if value%2 != 0: - r.append(key) - return r - - # compute and optimize CRC's LFSR - curval = [[("state", i)] for i in range(width)] - for i in range(data_width): - feedback = curval.pop() + [("din", i)] - for j in range(width-1): - if (polynom & (1<<(j+1))): - curval[j] += feedback - curval[j] = _optimize_eq(curval[j]) - curval.insert(0, feedback) - - # implement logic - for i in range(width): - xors = [] - for t, n in curval[i]: - if t == "state": - xors += [self.last[n]] - elif t == "din": - xors += [self.data[n]] - self.comb += self.next[i].eq(reduce(xor, xors)) - - -@ResetInserter() -@CEInserter() -class LiteEthMACCRC32(Module): - """IEEE 802.3 CRC - - Implement an IEEE 802.3 CRC generator/checker. - - Parameters - ---------- - data_width : int - Width of the data bus. - - Attributes - ---------- - d : in - Data input. - value : out - CRC value (used for generator). - error : out - CRC error (used for checker). - """ - width = 32 - polynom = 0x04C11DB7 - init = 2**width-1 - check = 0xC704DD7B - def __init__(self, data_width): - self.data = Signal(data_width) - self.value = Signal(self.width) - self.error = Signal() - - # # # - - self.submodules.engine = LiteEthMACCRCEngine(data_width, self.width, self.polynom) - reg = Signal(self.width, reset=self.init) - self.sync += reg.eq(self.engine.next) - self.comb += [ - self.engine.data.eq(self.data), - self.engine.last.eq(reg), - - self.value.eq(~reg[::-1]), - self.error.eq(self.engine.next != self.check) - ] - - -class LiteEthMACCRCInserter(Module): - """CRC Inserter - - Append a CRC at the end of each packet. - - Parameters - ---------- - description : description - description of the dataflow. - - Attributes - ---------- - sink : in - Packets input without CRC. - source : out - Packets output with CRC. - """ - def __init__(self, crc_class, description): - self.sink = sink = Sink(description) - self.source = source = Source(description) - self.busy = Signal() - - # # # - - dw = len(sink.data) - crc = crc_class(dw) - fsm = FSM(reset_state="IDLE") - self.submodules += crc, fsm - - fsm.act("IDLE", - crc.reset.eq(1), - sink.ack.eq(1), - If(sink.stb & sink.sop, - sink.ack.eq(0), - NextState("COPY"), - ) - ) - fsm.act("COPY", - crc.ce.eq(sink.stb & source.ack), - crc.data.eq(sink.data), - Record.connect(sink, source), - source.eop.eq(0), - If(sink.stb & sink.eop & source.ack, - NextState("INSERT"), - ) - ) - ratio = crc.width//dw - if ratio > 1: - cnt = Signal(max=ratio, reset=ratio-1) - cnt_done = Signal() - fsm.act("INSERT", - source.stb.eq(1), - chooser(crc.value, cnt, source.data, reverse=True), - If(cnt_done, - source.eop.eq(1), - If(source.ack, NextState("IDLE")) - ) - ) - self.comb += cnt_done.eq(cnt == 0) - self.sync += \ - If(fsm.ongoing("IDLE"), - cnt.eq(cnt.reset) - ).Elif(fsm.ongoing("INSERT") & ~cnt_done, - cnt.eq(cnt - source.ack) - ) - else: - fsm.act("INSERT", - source.stb.eq(1), - source.eop.eq(1), - source.data.eq(crc.value), - If(source.ack, NextState("IDLE")) - ) - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) - - -class LiteEthMACCRC32Inserter(LiteEthMACCRCInserter): - def __init__(self, description): - LiteEthMACCRCInserter.__init__(self, LiteEthMACCRC32, description) - - -class LiteEthMACCRCChecker(Module): - """CRC Checker - - Check CRC at the end of each packet. - - Parameters - ---------- - description : description - description of the dataflow. - - Attributes - ---------- - sink : in - Packets input with CRC. - source : out - Packets output without CRC and "error" set to 0 - on eop when CRC OK / set to 1 when CRC KO. - """ - def __init__(self, crc_class, description): - self.sink = sink = Sink(description) - self.source = source = Source(description) - self.busy = Signal() - - # # # - - dw = len(sink.data) - crc = crc_class(dw) - self.submodules += crc - ratio = crc.width//dw - - fifo = ResetInserter()(SyncFIFO(description, ratio + 1)) - self.submodules += fifo - - fsm = FSM(reset_state="RESET") - self.submodules += fsm - - fifo_in = Signal() - fifo_out = Signal() - fifo_full = Signal() - - self.comb += [ - fifo_full.eq(fifo.fifo.level == ratio), - fifo_in.eq(sink.stb & (~fifo_full | fifo_out)), - fifo_out.eq(source.stb & source.ack), - - Record.connect(sink, fifo.sink), - fifo.sink.stb.eq(fifo_in), - self.sink.ack.eq(fifo_in), - - source.stb.eq(sink.stb & fifo_full), - source.sop.eq(fifo.source.sop), - source.eop.eq(sink.eop), - fifo.source.ack.eq(fifo_out), - source.payload.eq(fifo.source.payload), - - source.error.eq(sink.error | crc.error), - ] - - fsm.act("RESET", - crc.reset.eq(1), - fifo.reset.eq(1), - NextState("IDLE"), - ) - self.comb += crc.data.eq(sink.data) - fsm.act("IDLE", - If(sink.stb & sink.sop & sink.ack, - crc.ce.eq(1), - NextState("COPY") - ) - ) - fsm.act("COPY", - If(sink.stb & sink.ack, - crc.ce.eq(1), - If(sink.eop, - NextState("RESET") - ) - ) - ) - self.comb += self.busy.eq(~fsm.ongoing("IDLE")) - - -class LiteEthMACCRC32Checker(LiteEthMACCRCChecker): - def __init__(self, description): - LiteEthMACCRCChecker.__init__(self, LiteEthMACCRC32, description) diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/core/gap.py b/litex/soc/misoc/cores/liteeth_mini/mac/core/gap.py deleted file mode 100644 index cfc9b281..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/core/gap.py +++ /dev/null @@ -1,42 +0,0 @@ -import math - -from migen import * -from migen.genlib.fsm import * - -from misoc.interconnect.stream import Sink, Source -from misoc.cores.liteeth_mini.common import eth_phy_description, eth_interpacket_gap - - -class LiteEthMACGap(Module): - def __init__(self, dw, ack_on_gap=False): - self.sink = sink = Sink(eth_phy_description(dw)) - self.source = source = Source(eth_phy_description(dw)) - - # # # - - gap = math.ceil(eth_interpacket_gap/(dw//8)) - counter = Signal(max=gap) - counter_reset = Signal() - counter_ce = Signal() - self.sync += \ - If(counter_reset, - counter.eq(0) - ).Elif(counter_ce, - counter.eq(counter + 1) - ) - - self.submodules.fsm = fsm = FSM(reset_state="COPY") - fsm.act("COPY", - counter_reset.eq(1), - Record.connect(sink, source), - If(sink.stb & sink.eop & sink.ack, - NextState("GAP") - ) - ) - fsm.act("GAP", - counter_ce.eq(1), - sink.ack.eq(int(ack_on_gap)), - If(counter == (gap-1), - NextState("COPY") - ) - ) diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/core/last_be.py b/litex/soc/misoc/cores/liteeth_mini/mac/core/last_be.py deleted file mode 100644 index ef3481e5..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/core/last_be.py +++ /dev/null @@ -1,46 +0,0 @@ -from migen import * - -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import eth_phy_description - - -class LiteEthMACTXLastBE(Module): - def __init__(self, dw): - self.sink = sink = Sink(eth_phy_description(dw)) - self.source = source = Source(eth_phy_description(dw)) - - # # # - - ongoing = Signal() - self.sync += \ - If(sink.stb & sink.ack, - If(sink.sop, - ongoing.eq(1) - ).Elif(sink.last_be, - ongoing.eq(0) - ) - ) - self.comb += [ - source.stb.eq(sink.stb & (sink.sop | ongoing)), - source.sop.eq(sink.sop), - source.eop.eq(sink.last_be), - source.data.eq(sink.data), - sink.ack.eq(source.ack) - ] - - -class LiteEthMACRXLastBE(Module): - def __init__(self, dw): - self.sink = sink = Sink(eth_phy_description(dw)) - self.source = source = Source(eth_phy_description(dw)) - - # # # - - self.comb += [ - source.stb.eq(sink.stb), - source.sop.eq(sink.sop), - source.eop.eq(sink.eop), - source.data.eq(sink.data), - source.last_be.eq(sink.eop), - sink.ack.eq(source.ack) - ] diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/core/padding.py b/litex/soc/misoc/cores/liteeth_mini/mac/core/padding.py deleted file mode 100644 index 4a37a10b..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/core/padding.py +++ /dev/null @@ -1,68 +0,0 @@ -import math - -from migen import * - -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import eth_phy_description - - -class LiteEthMACPaddingInserter(Module): - def __init__(self, dw, padding): - self.sink = sink = Sink(eth_phy_description(dw)) - self.source = source = Source(eth_phy_description(dw)) - - # # # - - padding_limit = math.ceil(padding/(dw/8))-1 - - counter = Signal(16, reset=1) - counter_done = Signal() - counter_reset = Signal() - counter_ce = Signal() - self.sync += If(counter_reset, - counter.eq(1) - ).Elif(counter_ce, - counter.eq(counter + 1) - ) - self.comb += [ - counter_reset.eq(sink.stb & sink.sop & sink.ack), - counter_ce.eq(source.stb & source.ack), - counter_done.eq(counter >= padding_limit), - ] - - self.submodules.fsm = fsm = FSM(reset_state="IDLE") - fsm.act("IDLE", - Record.connect(sink, source), - If(source.stb & source.ack, - counter_ce.eq(1), - If(sink.eop, - If(~counter_done, - source.eop.eq(0), - NextState("PADDING") - ) - ) - ) - ) - fsm.act("PADDING", - source.stb.eq(1), - source.eop.eq(counter_done), - source.data.eq(0), - If(source.ack, - If(counter_done, - NextState("IDLE") - ) - ) - ) - - -class LiteEthMACPaddingChecker(Module): - def __init__(self, dw, packet_min_length): - self.sink = sink = Sink(eth_phy_description(dw)) - self.source = source = Source(eth_phy_description(dw)) - - # # # - - # TODO: see if we should drop the packet when - # payload size < minimum ethernet payload size - self.comb += Record.connect(sink, source) - diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/core/preamble.py b/litex/soc/misoc/cores/liteeth_mini/mac/core/preamble.py deleted file mode 100644 index ebf7fe70..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/core/preamble.py +++ /dev/null @@ -1,156 +0,0 @@ -from migen import * -from migen.genlib.fsm import * -from migen.genlib.misc import chooser -from migen.genlib.record import Record - -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import eth_phy_description, eth_preamble - - -class LiteEthMACPreambleInserter(Module): - def __init__(self, dw): - self.sink = Sink(eth_phy_description(dw)) - self.source = Source(eth_phy_description(dw)) - - # # # - - preamble = Signal(64, reset=eth_preamble) - cnt_max = (64//dw)-1 - cnt = Signal(max=cnt_max+1) - clr_cnt = Signal() - inc_cnt = Signal() - - self.sync += \ - If(clr_cnt, - cnt.eq(0) - ).Elif(inc_cnt, - cnt.eq(cnt+1) - ) - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - fsm.act("IDLE", - self.sink.ack.eq(1), - clr_cnt.eq(1), - If(self.sink.stb & self.sink.sop, - self.sink.ack.eq(0), - NextState("INSERT"), - ) - ) - fsm.act("INSERT", - self.source.stb.eq(1), - self.source.sop.eq(cnt == 0), - chooser(preamble, cnt, self.source.data), - If(cnt == cnt_max, - If(self.source.ack, NextState("COPY")) - ).Else( - inc_cnt.eq(self.source.ack) - ) - ) - - self.comb += [ - self.source.data.eq(self.sink.data), - self.source.last_be.eq(self.sink.last_be) - ] - fsm.act("COPY", - Record.connect(self.sink, self.source, leave_out=set(["data", "last_be"])), - self.source.sop.eq(0), - - If(self.sink.stb & self.sink.eop & self.source.ack, - NextState("IDLE"), - ) - ) - - -class LiteEthMACPreambleChecker(Module): - def __init__(self, dw): - self.sink = Sink(eth_phy_description(dw)) - self.source = Source(eth_phy_description(dw)) - - # # # - - preamble = Signal(64, reset=eth_preamble) - cnt_max = (64//dw) - 1 - cnt = Signal(max=cnt_max+1) - clr_cnt = Signal() - inc_cnt = Signal() - - self.sync += \ - If(clr_cnt, - cnt.eq(0) - ).Elif(inc_cnt, - cnt.eq(cnt+1) - ) - - discard = Signal() - clr_discard = Signal() - set_discard = Signal() - - self.sync += \ - If(clr_discard, - discard.eq(0) - ).Elif(set_discard, - discard.eq(1) - ) - - sop = Signal() - clr_sop = Signal() - set_sop = Signal() - self.sync += \ - If(clr_sop, - sop.eq(0) - ).Elif(set_sop, - sop.eq(1) - ) - - ref = Signal(dw) - match = Signal() - self.comb += [ - chooser(preamble, cnt, ref), - match.eq(self.sink.data == ref) - ] - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - self.sink.ack.eq(1), - clr_cnt.eq(1), - clr_discard.eq(1), - If(self.sink.stb & self.sink.sop, - clr_cnt.eq(0), - inc_cnt.eq(1), - clr_discard.eq(0), - set_discard.eq(~match), - NextState("CHECK"), - ) - ) - fsm.act("CHECK", - self.sink.ack.eq(1), - If(self.sink.stb, - set_discard.eq(~match), - If(cnt == cnt_max, - If(discard | (~match), - NextState("IDLE") - ).Else( - set_sop.eq(1), - NextState("COPY") - ) - ).Else( - inc_cnt.eq(1) - ) - ) - ) - self.comb += [ - self.source.data.eq(self.sink.data), - self.source.last_be.eq(self.sink.last_be) - ] - fsm.act("COPY", - Record.connect(self.sink, self.source, leave_out=set(["data", "last_be"])), - self.source.sop.eq(sop), - clr_sop.eq(self.source.stb & self.source.ack), - - If(self.source.stb & self.source.eop & self.source.ack, - NextState("IDLE"), - ) - ) diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/frontend/sram.py b/litex/soc/misoc/cores/liteeth_mini/mac/frontend/sram.py deleted file mode 100644 index 623bf856..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/frontend/sram.py +++ /dev/null @@ -1,252 +0,0 @@ -from misoc import * - -from misoc.interconnect.csr import * -from misoc.interconnect.csr_eventmanager import * -from misoc.interconnect.stream import * - -from misoc.cores.liteeth_mini.common import eth_phy_description - - -class LiteEthMACSRAMWriter(Module, AutoCSR): - def __init__(self, dw, depth, nslots=2): - self.sink = sink = Sink(eth_phy_description(dw)) - self.crc_error = Signal() - - slotbits = max(log2_int(nslots), 1) - lengthbits = log2_int(depth*4) # length in bytes - - self._slot = CSRStatus(slotbits) - self._length = CSRStatus(lengthbits) - - self.submodules.ev = EventManager() - self.ev.available = EventSourceLevel() - self.ev.finalize() - - # # # - - # packet dropped if no slot available - sink.ack.reset = 1 - - # length computation - increment = Signal(3) - self.comb += \ - If(sink.last_be[3], - increment.eq(1) - ).Elif(sink.last_be[2], - increment.eq(2) - ).Elif(sink.last_be[1], - increment.eq(3) - ).Else( - increment.eq(4) - ) - counter = Signal(lengthbits) - counter_reset = Signal() - counter_ce = Signal() - self.sync += If(counter_reset, - counter.eq(0) - ).Elif(counter_ce, - counter.eq(counter + increment) - ) - - # slot computation - slot = Signal(slotbits) - slot_ce = Signal() - self.sync += If(slot_ce, slot.eq(slot + 1)) - - ongoing = Signal() - - # status fifo - fifo = SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots) - self.submodules += fifo - - # fsm - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - If(sink.stb & sink.sop, - If(fifo.sink.ack, - ongoing.eq(1), - counter_ce.eq(1), - NextState("WRITE") - ) - ) - ) - fsm.act("WRITE", - counter_ce.eq(sink.stb), - ongoing.eq(1), - If(sink.stb & sink.eop, - If((sink.error & sink.last_be) != 0, - NextState("DISCARD") - ).Else( - NextState("TERMINATE") - ) - ) - ) - fsm.act("DISCARD", - counter_reset.eq(1), - NextState("IDLE") - ) - self.comb += [ - fifo.sink.slot.eq(slot), - fifo.sink.length.eq(counter) - ] - fsm.act("TERMINATE", - counter_reset.eq(1), - slot_ce.eq(1), - fifo.sink.stb.eq(1), - NextState("IDLE") - ) - self.comb += [ - fifo.source.ack.eq(self.ev.available.clear), - self.ev.available.trigger.eq(fifo.source.stb), - self._slot.status.eq(fifo.source.slot), - self._length.status.eq(fifo.source.length), - ] - - # memory - mems = [None]*nslots - ports = [None]*nslots - for n in range(nslots): - mems[n] = Memory(dw, depth) - ports[n] = mems[n].get_port(write_capable=True) - self.specials += ports[n] - self.mems = mems - - cases = {} - for n, port in enumerate(ports): - cases[n] = [ - ports[n].adr.eq(counter[2:]), - ports[n].dat_w.eq(sink.data), - If(sink.stb & ongoing, - ports[n].we.eq(0xf) - ) - ] - self.comb += Case(slot, cases) - - -class LiteEthMACSRAMReader(Module, AutoCSR): - def __init__(self, dw, depth, nslots=2): - self.source = source = Source(eth_phy_description(dw)) - - slotbits = max(log2_int(nslots), 1) - lengthbits = log2_int(depth*4) # length in bytes - self.lengthbits = lengthbits - - self._start = CSR() - self._ready = CSRStatus() - self._slot = CSRStorage(slotbits) - self._length = CSRStorage(lengthbits) - - self.submodules.ev = EventManager() - self.ev.done = EventSourcePulse() - self.ev.finalize() - - # # # - - # command fifo - fifo = SyncFIFO([("slot", slotbits), ("length", lengthbits)], nslots) - self.submodules += fifo - self.comb += [ - fifo.sink.stb.eq(self._start.re), - fifo.sink.slot.eq(self._slot.storage), - fifo.sink.length.eq(self._length.storage), - self._ready.status.eq(fifo.sink.ack) - ] - - # length computation - counter = Signal(lengthbits) - counter_reset = Signal() - counter_ce = Signal() - self.sync += If(counter_reset, - counter.eq(0) - ).Elif(counter_ce, - counter.eq(counter + 4) - ) - - - # fsm - first = Signal() - last = Signal() - last_d = Signal() - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - counter_reset.eq(1), - If(fifo.source.stb, - NextState("CHECK") - ) - ) - fsm.act("CHECK", - If(~last_d, - NextState("SEND"), - ).Else( - NextState("END"), - ) - ) - length_lsb = fifo.source.length[0:2] - self.comb += [ - If(last, - If(length_lsb == 3, - source.last_be.eq(0b0010) - ).Elif(length_lsb == 2, - source.last_be.eq(0b0100) - ).Elif(length_lsb == 1, - source.last_be.eq(0b1000) - ).Else( - source.last_be.eq(0b0001) - ) - ) - ] - fsm.act("SEND", - source.stb.eq(1), - source.sop.eq(first), - source.eop.eq(last), - If(source.ack, - counter_ce.eq(~last), - NextState("CHECK") - ) - ) - fsm.act("END", - fifo.source.ack.eq(1), - self.ev.done.trigger.eq(1), - NextState("IDLE") - ) - - # first/last computation - self.sync += [ - If(fsm.ongoing("IDLE"), - first.eq(1) - ).Elif(source.stb & source.ack, - first.eq(0) - ) - ] - self.comb += last.eq((counter + 4) >= fifo.source.length) - self.sync += last_d.eq(last) - - # memory - rd_slot = fifo.source.slot - - mems = [None]*nslots - ports = [None]*nslots - for n in range(nslots): - mems[n] = Memory(dw, depth) - ports[n] = mems[n].get_port() - self.specials += ports[n] - self.mems = mems - - cases = {} - for n, port in enumerate(ports): - self.comb += ports[n].adr.eq(counter[2:]) - cases[n] = [source.data.eq(port.dat_r)] - self.comb += Case(rd_slot, cases) - - -class LiteEthMACSRAM(Module, AutoCSR): - def __init__(self, dw, depth, nrxslots, ntxslots): - self.submodules.writer = LiteEthMACSRAMWriter(dw, depth, nrxslots) - self.submodules.reader = LiteEthMACSRAMReader(dw, depth, ntxslots) - self.submodules.ev = SharedIRQ(self.writer.ev, self.reader.ev) - self.sink, self.source = self.writer.sink, self.reader.source diff --git a/litex/soc/misoc/cores/liteeth_mini/mac/frontend/wishbone.py b/litex/soc/misoc/cores/liteeth_mini/mac/frontend/wishbone.py deleted file mode 100644 index 80da1c90..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/mac/frontend/wishbone.py +++ /dev/null @@ -1,44 +0,0 @@ -from migen import * -from migen.fhdl.simplify import FullMemoryWE - -from misoc.interconnect import wishbone -from misoc.interconnect.csr import * -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import eth_phy_description, buffer_depth -from misoc.cores.liteeth_mini.mac.frontend import sram - - -class LiteEthMACWishboneInterface(Module, AutoCSR): - def __init__(self, dw, nrxslots=2, ntxslots=2): - self.sink = Sink(eth_phy_description(dw)) - self.source = Source(eth_phy_description(dw)) - self.bus = wishbone.Interface() - - # # # - - # storage in SRAM - sram_depth = buffer_depth//(dw//8) - self.submodules.sram = sram.LiteEthMACSRAM(dw, sram_depth, nrxslots, ntxslots) - self.comb += [ - Record.connect(self.sink, self.sram.sink), - Record.connect(self.sram.source, self.source) - ] - - # Wishbone interface - wb_rx_sram_ifs = [wishbone.SRAM(self.sram.writer.mems[n], read_only=True) - for n in range(nrxslots)] - # TODO: FullMemoryWE should move to Mibuild - wb_tx_sram_ifs = [FullMemoryWE()(wishbone.SRAM(self.sram.reader.mems[n], read_only=False)) - for n in range(ntxslots)] - wb_sram_ifs = wb_rx_sram_ifs + wb_tx_sram_ifs - - wb_slaves = [] - decoderoffset = log2_int(sram_depth) - decoderbits = log2_int(len(wb_sram_ifs)) - for n, wb_sram_if in enumerate(wb_sram_ifs): - def slave_filter(a, v=n): - return a[decoderoffset:decoderoffset+decoderbits] == v - wb_slaves.append((slave_filter, wb_sram_if.bus)) - self.submodules += wb_sram_if - wb_con = wishbone.Decoder(self.bus, wb_slaves, register=True) - self.submodules += wb_con diff --git a/litex/soc/misoc/cores/liteeth_mini/phy/__init__.py b/litex/soc/misoc/cores/liteeth_mini/phy/__init__.py deleted file mode 100644 index a5d5ae92..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/phy/__init__.py +++ /dev/null @@ -1,23 +0,0 @@ -from misoc.cores.liteeth_mini.common import * - - -def LiteEthPHY(clock_pads, pads, clk_freq=None, **kwargs): - # Autodetect PHY - if hasattr(clock_pads, "gtx") and len(pads.tx_data) == 8: - if hasattr(clock_pads, "tx"): - # This is a 10/100/1G PHY - from misoc.cores.liteeth_mini.phy.gmii_mii import LiteEthPHYGMIIMII - return LiteEthPHYGMIIMII(clock_pads, pads, clk_freq=clk_freq, **kwargs) - else: - # This is a pure 1G PHY - from misoc.cores.liteeth_mini.phy.gmii import LiteEthPHYGMII - return LiteEthPHYGMII(clock_pads, pads, **kwargs) - elif hasattr(pads, "rx_ctl"): - # This is a 10/100/1G RGMII PHY - raise ValueError("RGMII PHYs are specific to vendors (for now), use direct instantiation") - elif len(pads.tx_data) == 4: - # This is a MII PHY - from misoc.cores.liteeth_mini.phy.mii import LiteEthPHYMII - return LiteEthPHYMII(clock_pads, pads, **kwargs) - else: - raise ValueError("Unable to autodetect PHY from platform file, use direct instantiation") diff --git a/litex/soc/misoc/cores/liteeth_mini/phy/gmii.py b/litex/soc/misoc/cores/liteeth_mini/phy/gmii.py deleted file mode 100644 index bb3fc0bb..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/phy/gmii.py +++ /dev/null @@ -1,98 +0,0 @@ -from migen import * -from migen.genlib.io import DDROutput -from migen.genlib.resetsync import AsyncResetSynchronizer - -from misoc.cores.liteeth_mini.common import * - - -class LiteEthPHYGMIITX(Module): - def __init__(self, pads, pads_register=True): - self.sink = sink = Sink(eth_phy_description(8)) - - # # # - - if hasattr(pads, "tx_er"): - self.sync += pads.tx_er.eq(0) - pads_eq = [ - pads.tx_en.eq(sink.stb), - pads.tx_data.eq(sink.data) - ] - if pads_register: - self.sync += pads_eq - else: - self.comb += pads_eq - self.comb += sink.ack.eq(1) - - -class LiteEthPHYGMIIRX(Module): - def __init__(self, pads): - self.source = source = Source(eth_phy_description(8)) - - # # # - - dv_d = Signal() - self.sync += dv_d.eq(pads.dv) - - sop = Signal() - eop = Signal() - self.comb += [ - sop.eq(pads.dv & ~dv_d), - eop.eq(~pads.dv & dv_d) - ] - self.sync += [ - source.stb.eq(pads.dv), - source.sop.eq(sop), - source.data.eq(pads.rx_data) - ] - self.comb += source.eop.eq(eop) - - -class LiteEthPHYGMIICRG(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset, mii_mode=0): - self._reset = CSRStorage() - - # # # - - self.clock_domains.cd_eth_rx = ClockDomain() - self.clock_domains.cd_eth_tx = ClockDomain() - - # RX : Let the synthesis tool insert the appropriate clock buffer - self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx) - - # TX : GMII: Drive clock_pads.gtx, clock_pads.tx unused - # MII: Use PHY clock_pads.tx as eth_tx_clk, do not drive clock_pads.gtx - self.specials += DDROutput(1, mii_mode, clock_pads.gtx, ClockSignal("eth_tx")) - # XXX Xilinx specific, replace BUFGMUX with a generic clock buffer? - self.specials += Instance("BUFGMUX", - i_I0=self.cd_eth_rx.clk, - i_I1=clock_pads.tx, - i_S=mii_mode, - o_O=self.cd_eth_tx.clk) - - if with_hw_init_reset: - reset = Signal() - counter = Signal(max=512) - counter_done = Signal() - counter_ce = Signal() - self.sync += If(counter_ce, counter.eq(counter + 1)) - self.comb += [ - counter_done.eq(counter == 256), - counter_ce.eq(~counter_done), - reset.eq(~counter_done | self._reset.storage) - ] - else: - reset = self._reset.storage - self.comb += pads.rst_n.eq(~reset) - self.specials += [ - AsyncResetSynchronizer(self.cd_eth_tx, reset), - AsyncResetSynchronizer(self.cd_eth_rx, reset), - ] - - -class LiteEthPHYGMII(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset=True): - self.dw = 8 - self.submodules.crg = LiteEthPHYGMIICRG(clock_pads, pads, with_hw_init_reset) - self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYGMIITX(pads)) - self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYGMIIRX(pads)) - self.sink, self.source = self.tx.sink, self.rx.source diff --git a/litex/soc/misoc/cores/liteeth_mini/phy/gmii_mii.py b/litex/soc/misoc/cores/liteeth_mini/phy/gmii_mii.py deleted file mode 100644 index 6946c6c3..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/phy/gmii_mii.py +++ /dev/null @@ -1,170 +0,0 @@ -from migen import * -from migen.genlib.io import DDROutput -from migen.genlib.cdc import PulseSynchronizer - -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import * -from misoc.cores.liteeth_mini.phy.gmii import LiteEthPHYGMIICRG -from misoc.cores.liteeth_mini.phy.mii import LiteEthPHYMIITX, LiteEthPHYMIIRX -from misoc.cores.liteeth_mini.phy.gmii import LiteEthPHYGMIITX, LiteEthPHYGMIIRX - - -modes = { - "GMII": 0, - "MII": 1 -} - -tx_pads_layout = [("tx_er", 1), ("tx_en", 1), ("tx_data", 8)] -rx_pads_layout = [("rx_er", 1), ("dv", 1), ("rx_data", 8)] - - -class LiteEthPHYGMIIMIITX(Module): - def __init__(self, pads, mode): - self.sink = sink = Sink(eth_phy_description(8)) - - # # # - - gmii_tx_pads = Record(tx_pads_layout) - gmii_tx = LiteEthPHYGMIITX(gmii_tx_pads, pads_register=False) - self.submodules += gmii_tx - - mii_tx_pads = Record(tx_pads_layout) - mii_tx = LiteEthPHYMIITX(mii_tx_pads, pads_register=False) - self.submodules += mii_tx - - demux = Demultiplexer(eth_phy_description(8), 2) - self.submodules += demux - self.comb += [ - demux.sel.eq(mode == modes["MII"]), - Record.connect(sink, demux.sink), - Record.connect(demux.source0, gmii_tx.sink), - Record.connect(demux.source1, mii_tx.sink), - ] - - if hasattr(pads, "tx_er"): - self.comb += pads.tx_er.eq(0) - self.sync += [ - If(mode == modes["MII"], - pads.tx_en.eq(mii_tx_pads.tx_en), - pads.tx_data.eq(mii_tx_pads.tx_data), - ).Else( - pads.tx_en.eq(gmii_tx_pads.tx_en), - pads.tx_data.eq(gmii_tx_pads.tx_data), - ) - ] - - -class LiteEthPHYGMIIMIIRX(Module): - def __init__(self, pads, mode): - self.source = source = Source(eth_phy_description(8)) - - # # # - - pads_d = Record(rx_pads_layout) - self.sync += [ - pads_d.dv.eq(pads.dv), - pads_d.rx_data.eq(pads.rx_data) - ] - - gmii_rx = LiteEthPHYGMIIRX(pads_d) - self.submodules += gmii_rx - - mii_rx = LiteEthPHYMIIRX(pads_d) - self.submodules += mii_rx - - mux = Multiplexer(eth_phy_description(8), 2) - self.submodules += mux - self.comb += [ - mux.sel.eq(mode == modes["MII"]), - Record.connect(gmii_rx.source, mux.sink0), - Record.connect(mii_rx.source, mux.sink1), - Record.connect(mux.source, source) - ] - - -class LiteEthGMIIMIIModeDetection(Module, AutoCSR): - def __init__(self, clk_freq): - self.mode = Signal() - self._mode = CSRStatus() - - # # # - - mode = Signal() - update_mode = Signal() - self.sync += \ - If(update_mode, - self.mode.eq(mode) - ) - self.comb += self._mode.status.eq(self.mode) - - # Principle: - # sys_clk >= 125MHz - # eth_rx <= 125Mhz - # We generate ticks every 1024 clock cycles in eth_rx domain - # and measure ticks period in sys_clk domain. - - # Generate a tick every 1024 clock cycles (eth_rx clock domain) - eth_tick = Signal() - eth_counter = Signal(10) - self.sync.eth_rx += eth_counter.eq(eth_counter + 1) - self.comb += eth_tick.eq(eth_counter == 0) - - # Synchronize tick (sys clock domain) - sys_tick = Signal() - eth_ps = PulseSynchronizer("eth_rx", "sys") - self.comb += [ - eth_ps.i.eq(eth_tick), - sys_tick.eq(eth_ps.o) - ] - self.submodules += eth_ps - - # sys_clk domain counter - sys_counter = Signal(24) - sys_counter_reset = Signal() - sys_counter_ce = Signal() - self.sync += [ - If(sys_counter_reset, - sys_counter.eq(0) - ).Elif(sys_counter_ce, - sys_counter.eq(sys_counter + 1) - ) - ] - - fsm = FSM(reset_state="IDLE") - self.submodules += fsm - - fsm.act("IDLE", - sys_counter_reset.eq(1), - If(sys_tick, - NextState("COUNT") - ) - ) - fsm.act("COUNT", - sys_counter_ce.eq(1), - If(sys_tick, - NextState("DETECTION") - ) - ) - fsm.act("DETECTION", - update_mode.eq(1), - # if freq < 125MHz-5% use MII mode - If(sys_counter > int((clk_freq/125000000)*1024*1.05), - mode.eq(1) - # if freq >= 125MHz-5% use GMII mode - ).Else( - mode.eq(0) - ), - NextState("IDLE") - ) - - -class LiteEthPHYGMIIMII(Module, AutoCSR): - def __init__(self, clock_pads, pads, clk_freq, with_hw_init_reset=True): - self.dw = 8 - # Note: we can use GMII CRG since it also handles tx clock pad used for MII - self.submodules.mode_detection = LiteEthGMIIMIIModeDetection(clk_freq) - mode = self.mode_detection.mode - self.submodules.crg = LiteEthPHYGMIICRG(clock_pads, pads, with_hw_init_reset, mode == modes["MII"]) - self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYGMIIMIITX(pads, mode)) - self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYGMIIMIIRX(pads, mode)) - self.sink, self.source = self.tx.sink, self.rx.source diff --git a/litex/soc/misoc/cores/liteeth_mini/phy/loopback.py b/litex/soc/misoc/cores/liteeth_mini/phy/loopback.py deleted file mode 100644 index 28b1430e..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/phy/loopback.py +++ /dev/null @@ -1,35 +0,0 @@ -from migen import * - -from misoc.interconnect.csr import * -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import * -from misoc.cores.liteeth.mini.generic import * - - -class LiteEthPHYLoopbackCRG(Module, AutoCSR): - def __init__(self): - self._reset = CSRStorage() - - # # # - - self.clock_domains.cd_eth_rx = ClockDomain() - self.clock_domains.cd_eth_tx = ClockDomain() - self.comb += [ - self.cd_eth_rx.clk.eq(ClockSignal()), - self.cd_eth_tx.clk.eq(ClockSignal()) - ] - - reset = self._reset.storage - self.comb += [ - self.cd_eth_rx.rst.eq(reset), - self.cd_eth_tx.rst.eq(reset) - ] - - -class LiteEthPHYLoopback(Module, AutoCSR): - def __init__(self): - self.dw = 8 - self.submodules.crg = LiteEthLoopbackPHYCRG() - self.sink = Sink(eth_phy_description(8)) - self.source = Source(eth_phy_description(8)) - self.comb += Record.connect(self.sink, self.source) diff --git a/litex/soc/misoc/cores/liteeth_mini/phy/mii.py b/litex/soc/misoc/cores/liteeth_mini/phy/mii.py deleted file mode 100644 index c5bf5271..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/phy/mii.py +++ /dev/null @@ -1,110 +0,0 @@ -from migen import * - -from misoc.interconnect.csr import * -from misoc.interconnect.stream import * -from misoc.cores.liteeth_mini.common import * - - -def converter_description(dw): - payload_layout = [("data", dw)] - return EndpointDescription(payload_layout, packetized=True) - - -class LiteEthPHYMIITX(Module): - def __init__(self, pads, pads_register=True): - self.sink = sink = Sink(eth_phy_description(8)) - - # # # - - if hasattr(pads, "tx_er"): - self.sync += pads.tx_er.eq(0) - converter = Converter(converter_description(8), - converter_description(4)) - self.submodules += converter - self.comb += [ - converter.sink.stb.eq(sink.stb), - converter.sink.data.eq(sink.data), - sink.ack.eq(converter.sink.ack), - converter.source.ack.eq(1) - ] - pads_eq = [ - pads.tx_en.eq(converter.source.stb), - pads.tx_data.eq(converter.source.data) - ] - if pads_register: - self.sync += pads_eq - else: - self.comb += pads_eq - - -class LiteEthPHYMIIRX(Module): - def __init__(self, pads): - self.source = source = Source(eth_phy_description(8)) - - # # # - - sop = Signal(reset=1) - sop_set = Signal() - sop_clr = Signal() - self.sync += If(sop_set, sop.eq(1)).Elif(sop_clr, sop.eq(0)) - - converter = Converter(converter_description(4), - converter_description(8)) - converter = ResetInserter()(converter) - self.submodules += converter - - self.sync += [ - converter.reset.eq(~pads.dv), - converter.sink.stb.eq(1), - converter.sink.data.eq(pads.rx_data) - ] - self.sync += [ - sop_set.eq(~pads.dv), - sop_clr.eq(pads.dv) - ] - self.comb += [ - converter.sink.sop.eq(sop), - converter.sink.eop.eq(~pads.dv) - ] - self.comb += Record.connect(converter.source, source) - - -class LiteEthPHYMIICRG(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset): - self._reset = CSRStorage() - - # # # - - if hasattr(clock_pads, "phy"): - self.sync.base50 += clock_pads.phy.eq(~clock_pads.phy) - - self.clock_domains.cd_eth_rx = ClockDomain() - self.clock_domains.cd_eth_tx = ClockDomain() - self.comb += self.cd_eth_rx.clk.eq(clock_pads.rx) - self.comb += self.cd_eth_tx.clk.eq(clock_pads.tx) - - if with_hw_init_reset: - reset = Signal() - counter_done = Signal() - self.submodules.counter = counter = Counter(max=512) - self.comb += [ - counter_done.eq(counter.value == 256), - counter.ce.eq(~counter_done), - reset.eq(~counter_done | self._reset.storage) - ] - else: - reset = self._reset.storage - self.comb += pads.rst_n.eq(~reset) - self.specials += [ - AsyncResetSynchronizer(self.cd_eth_tx, reset), - AsyncResetSynchronizer(self.cd_eth_rx, reset), - ] - - -class LiteEthPHYMII(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset=True): - self.dw = 8 - self.submodules.crg = LiteEthPHYMIICRG(clock_pads, pads, with_hw_init_reset) - self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYMIITX(pads)) - self.submodules.rx = ClockDomainsRenamer("eth_tx")(LiteEthPHYMIIRX(pads)) - self.sink, self.source = self.tx.sink, self.rx.source diff --git a/litex/soc/misoc/cores/liteeth_mini/phy/s6rgmii.py b/litex/soc/misoc/cores/liteeth_mini/phy/s6rgmii.py deleted file mode 100644 index 1f312ace..00000000 --- a/litex/soc/misoc/cores/liteeth_mini/phy/s6rgmii.py +++ /dev/null @@ -1,161 +0,0 @@ -# RGMII PHY for Spartan-6 - -from migen import * -from migen.genlib.io import DDROutput -from migen.genlib.misc import WaitTimer -from migen.genlib.fsm import FSM, NextState - -from misoc.interconnect.stream import * -from misoc.interconnect.csr import * -from misoc.cores.liteeth_mini.common import * - - -class LiteEthPHYRGMIITX(Module): - def __init__(self, pads, pads_register=True): - self.sink = sink = Sink(eth_phy_description(8)) - - # # # - - self.specials += Instance("ODDR2", - p_DDR_ALIGNMENT="C0", p_INIT=0, p_SRTYPE="ASYNC", - i_C0=ClockSignal("eth_tx"), i_C1=~ClockSignal("eth_tx"), - i_CE=1, i_S=0, i_R=0, - i_D0=sink.stb, i_D1=sink.stb, o_Q=pads.tx_ctl, - ) - for i in range(4): - self.specials += Instance("ODDR2", - p_DDR_ALIGNMENT="C0", p_INIT=0, p_SRTYPE="ASYNC", - i_C0=ClockSignal("eth_tx"), i_C1=~ClockSignal("eth_tx"), - i_CE=1, i_S=0, i_R=0, - i_D0=sink.data[i], i_D1=sink.data[4+i], o_Q=pads.tx_data[i], - ) - self.comb += sink.ack.eq(1) - - -class LiteEthPHYRGMIIRX(Module): - def __init__(self, pads): - self.source = source = Source(eth_phy_description(8)) - - # # # - - rx_ctl = Signal() - rx_data = Signal(8) - - self.specials += Instance("IDDR2", - p_DDR_ALIGNMENT="C0", p_INIT_Q0=0, p_INIT_Q1=0, p_SRTYPE="ASYNC", - i_C0=ClockSignal("eth_rx"), i_C1=~ClockSignal("eth_rx"), - i_CE=1, i_S=0, i_R=0, - i_D=pads.rx_ctl, o_Q1=rx_ctl, - ) - for i in range(4): - self.specials += Instance("IDDR2", - p_DDR_ALIGNMENT="C0", p_INIT_Q0=0, p_INIT_Q1=0, p_SRTYPE="ASYNC", - i_C0=ClockSignal("eth_rx"), i_C1=~ClockSignal("eth_rx"), - i_CE=1, i_S=0, i_R=0, - i_D=pads.rx_data[i], o_Q0=rx_data[4+i], o_Q1=rx_data[i], - ) - - - rx_ctl_d = Signal() - self.sync += rx_ctl_d.eq(rx_ctl) - - sop = Signal() - eop = Signal() - self.comb += [ - sop.eq(rx_ctl & ~rx_ctl_d), - eop.eq(~rx_ctl & rx_ctl_d) - ] - self.sync += [ - source.stb.eq(rx_ctl), - source.sop.eq(sop), - source.data.eq(rx_data) - ] - self.comb += source.eop.eq(eop) - - -class LiteEthPHYRGMIICRG(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset): - self._reset = CSRStorage() - - # # # - - self.clock_domains.cd_eth_rx = ClockDomain() - self.clock_domains.cd_eth_tx = ClockDomain() - - - # RX - dcm_reset = Signal() - dcm_locked = Signal() - - timer = WaitTimer(1024) - fsm = FSM(reset_state="DCM_RESET") - self.submodules += timer, fsm - - fsm.act("DCM_RESET", - dcm_reset.eq(1), - timer.wait.eq(1), - If(timer.done, - timer.wait.eq(0), - NextState("DCM_WAIT") - ) - ) - fsm.act("DCM_WAIT", - timer.wait.eq(1), - If(timer.done, - NextState("DCM_CHECK_LOCK") - ) - ) - fsm.act("DCM_CHECK_LOCK", - If(~dcm_locked, - NextState("DCM_RESET") - ) - ) - - clk90_rx = Signal() - clk0_rx = Signal() - clk0_rx_bufg = Signal() - self.specials += Instance("DCM", - i_CLKIN=clock_pads.rx, - i_CLKFB=clk0_rx_bufg, - o_CLK0=clk0_rx, - o_CLK90=clk90_rx, - o_LOCKED=dcm_locked, - i_PSEN=0, - i_PSCLK=0, - i_PSINCDEC=0, - i_RST=dcm_reset - ) - - self.specials += Instance("BUFG", i_I=clk0_rx, o_O=clk0_rx_bufg) - self.specials += Instance("BUFG", i_I=clk90_rx, o_O=self.cd_eth_rx.clk) - - # TX - self.specials += DDROutput(1, 0, clock_pads.tx, ClockSignal("eth_tx")) - self.specials += Instance("BUFG", i_I=self.cd_eth_rx.clk, o_O=self.cd_eth_tx.clk) - - # Reset - if with_hw_init_reset: - reset = Signal() - counter_done = Signal() - self.submodules.counter = counter = Counter(max=512) - self.comb += [ - counter_done.eq(counter.value == 256), - counter.ce.eq(~counter_done), - reset.eq(~counter_done | self._reset.storage) - ] - else: - reset = self._reset.storage - self.comb += pads.rst_n.eq(~reset) - self.specials += [ - AsyncResetSynchronizer(self.cd_eth_tx, reset), - AsyncResetSynchronizer(self.cd_eth_rx, reset), - ] - - -class LiteEthPHYRGMII(Module, AutoCSR): - def __init__(self, clock_pads, pads, with_hw_init_reset=True): - self.dw = 8 - self.submodules.crg = LiteEthPHYRGMIICRG(clock_pads, pads, with_hw_init_reset) - self.submodules.tx = ClockDomainsRenamer("eth_tx")(LiteEthPHYRGMIITX(pads)) - self.submodules.rx = ClockDomainsRenamer("eth_rx")(LiteEthPHYRGMIIRX(pads)) - self.sink, self.source = self.tx.sink, self.rx.source diff --git a/litex/soc/misoc/cores/lm32/__init__.py b/litex/soc/misoc/cores/lm32/__init__.py deleted file mode 100644 index c2727f48..00000000 --- a/litex/soc/misoc/cores/lm32/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.lm32.core import LM32 diff --git a/litex/soc/misoc/cores/minicon/__init__.py b/litex/soc/misoc/cores/minicon/__init__.py deleted file mode 100644 index 6fba1a1f..00000000 --- a/litex/soc/misoc/cores/minicon/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.minicon.core import Minicon diff --git a/litex/soc/misoc/cores/minicon/test.py b/litex/soc/misoc/cores/minicon/test.py deleted file mode 100644 index b3eac769..00000000 --- a/litex/soc/misoc/cores/minicon/test.py +++ /dev/null @@ -1,195 +0,0 @@ -from migen import * -from migen.bus.transactions import TRead, TWrite -from migen.bus import wishbone -from migen.sim.generic import Simulator -from migen.sim import icarus -from mibuild.platforms import papilio_pro as board -from misoc import sdram -from misoc.mem.sdram.core.minicon import Minicon -from misoc.mem.sdram.phy import gensdrphy -from itertools import chain -from os.path import isfile -import sys - -clk_freq = 80000000 - -from math import ceil - - -def ns(t, margin=True): - clk_period_ns = 1000000000/clk_freq - if margin: - t += clk_period_ns/2 - return ceil(t/clk_period_ns) - - -class MiniconTB(Module): - def __init__(self, sdrphy, dfi, sdram_geom, sdram_timing, pads, sdram_clk): - - self.clk_freq = 80000000 - phy_settings = sdrphy.settings - rdphase = phy_settings.rdphase - self.submodules.slave = Minicon(phy_settings, sdram_geom, sdram_timing) - - self.submodules.tap = wishbone.Tap(self.slave.bus) - self.submodules.dc = dc = wishbone.DownConverter(32, phy_settings.nphases*len(dfi.phases[rdphase].rddata)) - self.submodules.master = wishbone.Initiator(self.genxfers(), bus=dc.wishbone_i) - self.submodules.intercon = wishbone.InterconnectPointToPoint(dc.wishbone_o, self.slave.bus) - - self.submodules.sdrphy = self.sdrphy = sdrphy - self.dfi = dfi - self.pads = pads - - self.specials += Instance("mt48lc4m16a2", - io_Dq=pads.dq, - i_Addr=pads.a, - i_Ba=pads.ba, - i_Clk=ClockSignal(), - i_Cke=pads.cke, - i_Cs_n=pads.cs_n, - i_Ras_n=pads.ras_n, - i_Cas_n=pads.cas_n, - i_We_n=pads.we_n, - i_Dqm=pads.dm - ) - - def genxfers(self): - cycle = 0 - for a in chain(range(4), range(256, 260), range(1024, 1028)): - t = TRead(a) - yield t - print("read {} in {} cycles".format(t.data, t.latency)) - for a in chain(range(4), range(256, 260), range(1024, 1028), range(4096, 4100)): - t = TWrite(a, 0xaa55aa55+cycle) - cycle += 1 - yield t - print("read {} in {} cycles".format(t.data, t.latency)) - for a in chain(range(4), range(256, 260), range(1024, 1028), range(4096, 4100)): - t = TRead(a) - yield t - print("read {} in {} cycles".format(t.data, t.latency)) - - def gen_simulation(self, selfp): - dfi = selfp.dfi - phy = self.sdrphy - rdphase = phy.settings.rdphase - cycle = 0 - - while True: - yield - - -class MyTopLevel: - def __init__(self, vcd_name=None, vcd_level=1, - top_name="top", dut_type="dut", dut_name="dut", - cd_name="sys", clk_period=10): - self.vcd_name = vcd_name - self.vcd_level = vcd_level - self.top_name = top_name - self.dut_type = dut_type - self.dut_name = dut_name - - self._cd_name = cd_name - self._clk_period = clk_period - - cd = ClockDomain(self._cd_name) - cd_ps = ClockDomain("sys_ps") - self.clock_domains = [cd, cd_ps] - self.ios = {cd.clk, cd.rst, cd_ps.clk} - - def get(self, sockaddr): - template1 = """`timescale 1ns / 1ps - -module {top_name}(); - -reg {clk_name}; -reg {rst_name}; -reg sys_ps_clk; - -initial begin - {rst_name} <= 1'b1; - @(posedge {clk_name}); - {rst_name} <= 1'b0; -end - -always begin - {clk_name} <= 1'b0; - #{hclk_period}; - {clk_name} <= 1'b1; - #{hclk_period}; -end - -always @(posedge {clk_name} or negedge {clk_name}) - sys_ps_clk <= #({hclk_period}*2-3) {clk_name}; - -{dut_type} {dut_name}( - .{rst_name}({rst_name}), - .{clk_name}({clk_name}), - .sys_ps_clk(sys_ps_clk) -); - -initial $migensim_connect("{sockaddr}"); -always @(posedge {clk_name}) $migensim_tick; -""" - template2 = """ -initial begin - $dumpfile("{vcd_name}"); - $dumpvars({vcd_level}, {dut_name}); -end -""" - r = template1.format(top_name=self.top_name, - dut_type=self.dut_type, - dut_name=self.dut_name, - clk_name=self._cd_name + "_clk", - rst_name=self._cd_name + "_rst", - hclk_period=str(self._clk_period/2), - sockaddr=sockaddr) - if self.vcd_name is not None: - r += template2.format(vcd_name=self.vcd_name, - vcd_level=str(self.vcd_level), - dut_name=self.dut_name) - r += "\nendmodule" - return r - - -if __name__ == "__main__": - - plat = board.Platform() - - sdram_geom = sdram.GeomSettings( - bankbits=2, - rowbits=12, - colbits=8 - ) - - sdram_timing = sdram.TimingSettings( - tRP=ns(15), - tRCD=ns(15), - tWR=ns(14), - tWTR=2, - tREFI=ns(64*1000*1000/4096, False), - tRFC=ns(66), - req_queue_size=8, - read_time=32, - write_time=16 - ) - - sdram_pads = plat.request("sdram") - sdram_clk = plat.request("sdram_clock") - - sdrphy = gensdrphy.GENSDRPHY(sdram_pads) - -# This sets CL to 2 during LMR done on 1st cycle - sdram_pads.a.reset = 1<<5 - - s = MiniconTB(sdrphy, sdrphy.dfi, sdram_geom, sdram_timing, pads=sdram_pads, sdram_clk=sdram_clk) - - extra_files = ["sdram_model/mt48lc4m16a2.v"] - - if not isfile(extra_files[0]): - print("ERROR: You need to download Micron Verilog simulation model for MT48LC4M16A2 and put it in sdram_model/mt48lc4m16a2.v") - print("File can be downloaded from this URL: http://www.micron.com/-/media/documents/products/sim%20model/dram/dram/4054mt48lc4m16a2.zip") - sys.exit(1) - - with Simulator(s, MyTopLevel("top.vcd", clk_period=int(1/0.08)), icarus.Runner(extra_files=extra_files, keep_files=True)) as sim: - sim.run(5000) diff --git a/litex/soc/misoc/cores/mor1kx/__init__.py b/litex/soc/misoc/cores/mor1kx/__init__.py deleted file mode 100644 index e92714ae..00000000 --- a/litex/soc/misoc/cores/mor1kx/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.mor1kx.core import MOR1KX diff --git a/litex/soc/misoc/cores/mxcrg.v b/litex/soc/misoc/cores/mxcrg.v deleted file mode 100644 index 140c8483..00000000 --- a/litex/soc/misoc/cores/mxcrg.v +++ /dev/null @@ -1,247 +0,0 @@ -module mxcrg #( - parameter in_period = 0.0, - parameter f_mult = 0, - parameter f_div = 0, - parameter clk2x_period = (in_period*f_div)/(2.0*f_mult) -) ( - input clk50_pad, - input trigger_reset, - - output sys_clk, - output reg sys_rst, - - /* Reset NOR flash */ - output norflash_rst_n, - - /* DDR PHY clocks */ - output clk2x_270, - output clk4x_wr, - output clk4x_wr_strb, - output clk4x_rd, - output clk4x_rd_strb, - - /* DDR off-chip clocking */ - output ddr_clk_pad_p, - output ddr_clk_pad_n, - - /* Base clock, buffered */ - output base50_clk -); - -/* - * Reset - */ - -reg [19:0] rst_debounce; -always @(posedge sys_clk) begin - if(trigger_reset) - rst_debounce <= 20'hFFFFF; - else if(rst_debounce != 20'd0) - rst_debounce <= rst_debounce - 20'd1; - sys_rst <= rst_debounce != 20'd0; -end - -initial rst_debounce <= 20'hFFFFF; - -/* - * We must release the Flash reset before the system reset - * because the Flash needs some time to come out of reset - * and the CPU begins fetching instructions from it - * as soon as the system reset is released. - * From datasheet, minimum reset pulse width is 100ns - * and reset-to-read time is 150ns. - */ - -reg [7:0] flash_rstcounter; - -always @(posedge sys_clk) begin - if(trigger_reset) - flash_rstcounter <= 8'd0; - else if(~flash_rstcounter[7]) - flash_rstcounter <= flash_rstcounter + 8'd1; -end - -initial flash_rstcounter <= 8'd0; - -assign norflash_rst_n = flash_rstcounter[7]; - -/* - * Clock management. Inspired by the NWL reference design. - */ - -wire sdr_clk50; -wire clkdiv; - -IBUF #( - .IOSTANDARD("DEFAULT") -) clk2_iob ( - .I(clk50_pad), - .O(sdr_clk50) -); - -BUFIO2 #( - .DIVIDE(1), - .DIVIDE_BYPASS("FALSE"), - .I_INVERT("FALSE") -) bufio2_inst2 ( - .I(sdr_clk50), - .IOCLK(), - .DIVCLK(clkdiv), - .SERDESSTROBE() -); - -wire pll_lckd; -wire buf_pll_fb_out; -wire pllout0; -wire pllout1; -wire pllout2; -wire pllout3; -wire pllout4; -wire pllout5; - -PLL_ADV #( - .BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(4*f_mult), - .CLKFBOUT_PHASE(0.0), - .CLKIN1_PERIOD(in_period), - .CLKIN2_PERIOD(in_period), - - .CLKOUT0_DIVIDE(f_div), - .CLKOUT0_DUTY_CYCLE(0.5), - .CLKOUT0_PHASE(0.0), - - .CLKOUT1_DIVIDE(f_div), - .CLKOUT1_DUTY_CYCLE(0.5), - .CLKOUT1_PHASE(0.0), - - .CLKOUT2_DIVIDE(2*f_div), - .CLKOUT2_DUTY_CYCLE(0.5), - .CLKOUT2_PHASE(270.0), - - .CLKOUT3_DIVIDE(4*f_div), - .CLKOUT3_DUTY_CYCLE(0.5), - .CLKOUT3_PHASE(0.0), - - .CLKOUT4_DIVIDE(4*f_mult), - .CLKOUT4_DUTY_CYCLE(0.5), - .CLKOUT4_PHASE(0.0), - - .CLKOUT5_DIVIDE(2*f_div), - .CLKOUT5_DUTY_CYCLE(0.5), - .CLKOUT5_PHASE(250.0), - - .COMPENSATION("INTERNAL"), - .DIVCLK_DIVIDE(1), - .REF_JITTER(0.100), - .CLK_FEEDBACK("CLKFBOUT"), - .SIM_DEVICE("SPARTAN6") -) pll ( - .CLKFBDCM(), - .CLKFBOUT(buf_pll_fb_out), - .CLKOUT0(pllout0), /* < x4 clock for writes */ - .CLKOUT1(pllout1), /* < x4 clock for reads */ - .CLKOUT2(pllout2), /* < x2 270 clock for DQS, memory address and control signals */ - .CLKOUT3(pllout3), /* < x1 clock for system and memory controller */ - .CLKOUT4(pllout4), /* < buffered clk50 */ - .CLKOUT5(pllout5), /* < x2 clock to off-chip DDR */ - .CLKOUTDCM0(), - .CLKOUTDCM1(), - .CLKOUTDCM2(), - .CLKOUTDCM3(), - .CLKOUTDCM4(), - .CLKOUTDCM5(), - .DO(), - .DRDY(), - .LOCKED(pll_lckd), - .CLKFBIN(buf_pll_fb_out), - .CLKIN1(clkdiv), - .CLKIN2(1'b0), - .CLKINSEL(1'b1), - .DADDR(5'b00000), - .DCLK(1'b0), - .DEN(1'b0), - .DI(16'h0000), - .DWE(1'b0), - .RST(1'b0), - .REL(1'b0) -); - -BUFPLL #( - .DIVIDE(4) -) wr_bufpll ( - .PLLIN(pllout0), - .GCLK(sys_clk), - .LOCKED(pll_lckd), - .IOCLK(clk4x_wr), - .LOCK(), - .SERDESSTROBE(clk4x_wr_strb) -); - -BUFPLL #( - .DIVIDE(4) -) rd_bufpll ( - .PLLIN(pllout1), - .GCLK(sys_clk), - .LOCKED(pll_lckd), - .IOCLK(clk4x_rd), - .LOCK(), - .SERDESSTROBE(clk4x_rd_strb) -); - -BUFG bufg_x2_2( - .I(pllout2), - .O(clk2x_270) -); - -BUFG bufg_x1( - .I(pllout3), - .O(sys_clk) -); - -wire base50_clk; -BUFG bufg_50( - .I(pllout4), - .O(base50_clk) -); - -wire clk2x_off; -BUFG bufg_x2_offclk( - .I(pllout5), - .O(clk2x_off) -); - - -/* - * SDRAM clock - */ - -ODDR2 #( - .DDR_ALIGNMENT("NONE"), - .INIT(1'b0), - .SRTYPE("SYNC") -) sd_clk_forward_p ( - .Q(ddr_clk_pad_p), - .C0(clk2x_off), - .C1(~clk2x_off), - .CE(1'b1), - .D0(1'b1), - .D1(1'b0), - .R(1'b0), - .S(1'b0) -); -ODDR2 #( - .DDR_ALIGNMENT("NONE"), - .INIT(1'b0), - .SRTYPE("SYNC") -) sd_clk_forward_n ( - .Q(ddr_clk_pad_n), - .C0(clk2x_off), - .C1(~clk2x_off), - .CE(1'b1), - .D0(1'b0), - .D1(1'b1), - .R(1'b0), - .S(1'b0) -); - -endmodule diff --git a/litex/soc/misoc/cores/sdram_phy/__init__.py b/litex/soc/misoc/cores/sdram_phy/__init__.py deleted file mode 100644 index c2f449af..00000000 --- a/litex/soc/misoc/cores/sdram_phy/__init__.py +++ /dev/null @@ -1,3 +0,0 @@ -from misoc.cores.sdram_phy.gensdrphy import GENSDRPHY -from misoc.cores.sdram_phy.s6ddrphy import S6HalfRateDDRPHY, S6QuarterRateDDRPHY -from misoc.cores.sdram_phy.k7ddrphy import K7DDRPHY diff --git a/litex/soc/misoc/cores/spi/__init__.py b/litex/soc/misoc/cores/spi/__init__.py deleted file mode 100644 index 289e12f4..00000000 --- a/litex/soc/misoc/cores/spi/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.spi.core import SPIMaster diff --git a/litex/soc/misoc/cores/uart/__init__.py b/litex/soc/misoc/cores/uart/__init__.py deleted file mode 100644 index c98aad68..00000000 --- a/litex/soc/misoc/cores/uart/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from misoc.cores.uart.core import UART, RS232PHY diff --git a/litex/soc/misoc/cores/uart/test.py b/litex/soc/misoc/cores/uart/test.py deleted file mode 100644 index 71318c7a..00000000 --- a/litex/soc/misoc/cores/uart/test.py +++ /dev/null @@ -1,97 +0,0 @@ -# XXX Adapt test to new architecture -class UARTTB(Module): - def __init__(self): - self.clk_freq = 83333333 - self.baud = 3000000 - self.pads = Record([("rx", 1), ("tx", 1)]) - self.submodules.slave = UART(self.pads, self.clk_freq, self.baud) - - def wait_for(self, ns_time): - freq_in_ghz = self.clk_freq/(10**9) - period = 1/freq_in_ghz - num_loops = int(ns_time/period) - for i in range(num_loops+1): - yield - - def gen_simulation(self, selfp): - baud_in_ghz = self.baud/(10**9) - uart_period = int(1/baud_in_ghz) - half_uart_period = int(1/(2*baud_in_ghz)) - - # Set TX an RX lines idle - selfp.pads.tx = 1 - selfp.pads.rx = 1 - yield - - # First send a few characters - - tx_string = "01234" - print("Sending string: " + tx_string) - for c in tx_string: - selfp.slave._r_rxtx.r = ord(c) - selfp.slave._r_rxtx.re = 1 - yield - selfp.slave._r_rxtx.re = 0 - - yield from self.wait_for(half_uart_period) - - if selfp.pads.tx: - print("FAILURE: no start bit sent") - - val = 0 - for i in range(8): - yield from self.wait_for(uart_period) - val >>= 1 - if selfp.pads.tx: - val |= 0x80 - - yield from self.wait_for(uart_period) - - if selfp.pads.tx == 0: - print("FAILURE: no stop bit sent") - - if ord(c) != val: - print("FAILURE: sent decimal value "+str(val)+" (char "+chr(val)+") instead of "+c) - else: - print("SUCCESS: sent "+c) - while selfp.slave.ev.tx.trigger != 1: - yield - - # Then receive a character - - rx_string = '5' - print("Receiving character "+rx_string) - rx_value = ord(rx_string) - for i in range(11): - if (i == 0): - # start bit - selfp.pads.rx = 0 - elif (i == 9): - # stop bit - selfp.pads.rx = 1 - elif (i == 10): - selfp.pads.rx = 1 - break - else: - selfp.pads.rx = 1 if (rx_value & 1) else 0 - rx_value >>= 1 - yield from self.wait_for(uart_period) - - rx_value = ord(rx_string) - received_value = selfp.slave._r_rxtx.w - if (received_value == rx_value): - print("RX SUCCESS: ") - else: - print("RX FAILURE: ") - - print("received "+chr(received_value)) - - while True: - yield - -if __name__ == "__main__": - from migen.sim.generic import Simulator, TopLevel - from migen.sim import icarus - with Simulator(UARTTB(), TopLevel("top.vcd", clk_period=int(1/0.08333333)), - icarus.Runner(keep_files=False)) as s: - s.run(20000) diff --git a/litex/soc/misoc/integration/__init__.py b/litex/soc/misoc/integration/__init__.py deleted file mode 100644 index 2979fa9d..00000000 --- a/litex/soc/misoc/integration/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from misoc.integration.soc_core import SoCCore -from misoc.integration.soc_sdram import SoCSDRAM diff --git a/litex/soc/misoc/targets/mlabs_video.py b/litex/soc/misoc/targets/mlabs_video.py deleted file mode 100644 index 670c7fc4..00000000 --- a/litex/soc/misoc/targets/mlabs_video.py +++ /dev/null @@ -1,215 +0,0 @@ -#!/usr/bin/env python3 - -import argparse -import os -from fractions import Fraction -from math import ceil - -from migen import * -from migen.build.generic_platform import ConstraintError -from migen.build.platforms import mixxeo, m1 - -from misoc.cores.sdram_settings import MT46V32M16 -from misoc.cores.sdram_phy import S6HalfRateDDRPHY -from misoc.cores import nor_flash_16 -# TODO: from misoc.cores import framebuffer -from misoc.cores import gpio -from misoc.cores.liteeth_mini.phy import LiteEthPHY -from misoc.cores.liteeth_mini.mac import LiteEthMAC -from misoc.integration.soc_core import mem_decoder -from misoc.integration.soc_sdram import * -from misoc.integration.builder 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_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.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("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)) - - -class _MXClockPads: - def __init__(self, platform): - self.clk50 = platform.request("clk50") - self.trigger_reset = 0 - try: - self.trigger_reset = platform.request("user_btn", 1) - except ConstraintError: - pass - self.norflash_rst_n = platform.request("norflash_rst_n") - ddram_clock = platform.request("ddram_clock") - self.ddr_clk_p = ddram_clock.p - self.ddr_clk_n = ddram_clock.n - - -class BaseSoC(SoCSDRAM): - def __init__(self, platform_name="mixxeo", **kwargs): - if platform_name == "mixxeo": - platform = mixxeo.Platform() - elif platform_name == "m1": - platform = m1.Platform() - else: - raise ValueError - SoCSDRAM.__init__(self, platform, - clk_freq=(83 + Fraction(1, 3))*1000000, - cpu_reset_address=0x00180000, - **kwargs) - - self.submodules.crg = _MXCRG(_MXClockPads(platform), self.clk_freq) - - if not self.integrated_main_ram_size: - sdram_module = MT46V32M16(self.clk_freq) - self.submodules.ddrphy = S6HalfRateDDRPHY(platform.request("ddram"), - sdram_module.memtype, - rd_bitslip=0, - wr_bitslip=3, - dqs_ddr_alignment="C1") - self.register_sdram(self.ddrphy, "lasmicon", - sdram_module.geom_settings, sdram_module.timing_settings) - self.comb += [ - self.ddrphy.clk4x_wr_strb.eq(self.crg.clk4x_wr_strb), - self.ddrphy.clk4x_rd_strb.eq(self.crg.clk4x_rd_strb) - ] - - if not self.integrated_rom_size: - clk_period_ns = 1000000000/self.clk_freq - self.submodules.norflash = nor_flash_16.NorFlash16( - platform.request("norflash"), - ceil(110/clk_period_ns), ceil(50/clk_period_ns)) - self.flash_boot_address = 0x001a0000 - self.register_rom(self.norflash.bus) - - platform.add_platform_command(""" -INST "mxcrg/wr_bufpll" LOC = "BUFPLL_X0Y2"; -INST "mxcrg/rd_bufpll" LOC = "BUFPLL_X0Y3"; -""") - platform.add_source(os.path.join(misoc_directory, "cores", "mxcrg.v")) - - -class MiniSoC(BaseSoC): - csr_map = { - "ethphy": 16, - "ethmac": 17, - } - csr_map.update(BaseSoC.csr_map) - - interrupt_map = { - "ethmac": 2, - } - interrupt_map.update(BaseSoC.interrupt_map) - - mem_map = { - "ethmac": 0x30000000, # (shadow @0xb0000000) - } - mem_map.update(BaseSoC.mem_map) - - def __init__(self, *args, **kwargs): - BaseSoC.__init__(self, *args, **kwargs) - - platform = self.platform - if platform.name == "mixxeo": - self.submodules.leds = gpio.GPIOOut(platform.request("user_led")) - if platform.name == "m1": - self.submodules.buttons = gpio.GPIOIn(Cat(platform.request("user_btn", 0), - platform.request("user_btn", 2))) - self.submodules.leds = gpio.GPIOOut(Cat(platform.request("user_led", i) for i in range(2))) - - self.submodules.ethphy = LiteEthPHY(platform.request("eth_clocks"), - platform.request("eth")) - self.submodules.ethmac = LiteEthMAC(phy=self.ethphy, dw=32, interface="wishbone") - self.add_wb_slave(mem_decoder(self.mem_map["ethmac"]), self.ethmac.bus) - self.add_memory_region("ethmac", self.mem_map["ethmac"] | self.shadow_base, 0x2000) - - -def get_vga_dvi(platform): - try: - pads_vga = platform.request("vga_out") - except ConstraintError: - pads_vga = None - try: - pads_dvi = platform.request("dvi_out") - except ConstraintError: - pads_dvi = None - else: - platform.add_platform_command(""" -PIN "dviout_pix_bufg.O" CLOCK_DEDICATED_ROUTE = FALSE; -""") - return pads_vga, pads_dvi - - -def add_vga_tig(platform, fb): - platform.add_platform_command(""" -NET "{vga_clk}" TNM_NET = "GRPvga_clk"; -NET "sys_clk" TNM_NET = "GRPsys_clk"; -TIMESPEC "TSise_sucks1" = FROM "GRPvga_clk" TO "GRPsys_clk" TIG; -TIMESPEC "TSise_sucks2" = FROM "GRPsys_clk" TO "GRPvga_clk" TIG; -""", vga_clk=fb.driver.clocking.cd_pix.clk) - - -class FramebufferSoC(MiniSoC): - csr_map = { - "fb": 18, - } - csr_map.update(MiniSoC.csr_map) - - def __init__(self, *args, **kwargs): - MiniSoC.__init__(self, *args, **kwargs) - pads_vga, pads_dvi = get_vga_dvi(platform) - self.submodules.fb = framebuffer.Framebuffer(pads_vga, pads_dvi, - self.sdram.crossbar.get_master()) - add_vga_tig(platform, self.fb) - - -def main(): - parser = argparse.ArgumentParser(description="MiSoC port to the Mixxeo and Milkymist One") - builder_args(parser) - soc_sdram_args(parser) - parser.add_argument("--platform", default="mixxeo", - help="platform to build for: mixxeo, m1") - parser.add_argument("--soc-type", default="base", - help="SoC type: base, mini, framebuffer") - args = parser.parse_args() - - cls = { - "base": BaseSoC, - "mini": MiniSoC, - "framebuffer": FramebufferSoC - }[args.soc_type] - soc = cls(args.platform, **soc_sdram_argdict(args)) - builder = Builder(soc, **builder_argdict(args)) - builder.build() - - -if __name__ == "__main__": - main() diff --git a/litex/soc/setup.py b/litex/soc/setup.py deleted file mode 100644 index d8473447..00000000 --- a/litex/soc/setup.py +++ /dev/null @@ -1,41 +0,0 @@ -#!/usr/bin/env python3 - -import sys -from setuptools import setup -from setuptools import find_packages - - -if sys.version_info[:3] < (3, 3): - raise SystemExit("You need Python 3.3+") - - -setup( - name="misoc", - version="0.1", - description="a high performance and small footprint SoC based on Migen", - long_description=open("README").read(), - author="Sebastien Bourdeauducq", - author_email="sb@m-labs.hk", - url="http://m-labs.hk", - download_url="https://github.com/m-labs/misoc", - license="BSD", - platforms=["Any"], - keywords="HDL ASIC FPGA hardware design", - classifiers=[ - "Topic :: Scientific/Engineering :: Electronic Design Automation (EDA)", - "Environment :: Console", - "Development Status :: Alpha", - "Intended Audience :: Developers", - "License :: OSI Approved :: BSD License", - "Operating System :: OS Independent", - "Programming Language :: Python", - ], - packages=find_packages(), - include_package_data=True, - entry_points={ - "console_scripts": [ - "flterm=misoc.tools.flterm:main", - "mkmscimg=misoc.tools.mkmscimg:main", - ], - }, -) diff --git a/litex/soc/misoc/software/bios/Makefile b/litex/soc/software/bios/Makefile similarity index 87% rename from litex/soc/misoc/software/bios/Makefile rename to litex/soc/software/bios/Makefile index ca23cec8..b5be8713 100644 --- a/litex/soc/misoc/software/bios/Makefile +++ b/litex/soc/software/bios/Makefile @@ -1,5 +1,5 @@ include ../include/generated/variables.mak -include $(MISOC_DIRECTORY)/software/common.mak +include $(SOC_DIRECTORY)/software/common.mak OBJECTS=isr.o sdram.o main.o boot-helper-$(CPU).o boot.o dataflow.o @@ -8,7 +8,7 @@ all: bios.bin %.bin: %.elf $(OBJCOPY) -O binary $< $@ chmod -x $@ - $(PYTHON) -m misoc.tools.mkmscimg $@ + $(PYTHON) -m litex.soc.tools.mkmscimg $@ bios.elf: $(BIOS_DIRECTORY)/linker.ld $(OBJECTS) diff --git a/litex/soc/misoc/software/bios/boot-helper-lm32.S b/litex/soc/software/bios/boot-helper-lm32.S similarity index 100% rename from litex/soc/misoc/software/bios/boot-helper-lm32.S rename to litex/soc/software/bios/boot-helper-lm32.S diff --git a/litex/soc/misoc/software/bios/boot-helper-or1k.S b/litex/soc/software/bios/boot-helper-or1k.S similarity index 100% rename from litex/soc/misoc/software/bios/boot-helper-or1k.S rename to litex/soc/software/bios/boot-helper-or1k.S diff --git a/litex/soc/misoc/software/bios/boot.c b/litex/soc/software/bios/boot.c similarity index 100% rename from litex/soc/misoc/software/bios/boot.c rename to litex/soc/software/bios/boot.c diff --git a/litex/soc/misoc/software/bios/boot.h b/litex/soc/software/bios/boot.h similarity index 100% rename from litex/soc/misoc/software/bios/boot.h rename to litex/soc/software/bios/boot.h diff --git a/litex/soc/misoc/software/bios/dataflow.c b/litex/soc/software/bios/dataflow.c similarity index 100% rename from litex/soc/misoc/software/bios/dataflow.c rename to litex/soc/software/bios/dataflow.c diff --git a/litex/soc/misoc/software/bios/dataflow.h b/litex/soc/software/bios/dataflow.h similarity index 100% rename from litex/soc/misoc/software/bios/dataflow.h rename to litex/soc/software/bios/dataflow.h diff --git a/litex/soc/misoc/software/bios/isr.c b/litex/soc/software/bios/isr.c similarity index 100% rename from litex/soc/misoc/software/bios/isr.c rename to litex/soc/software/bios/isr.c diff --git a/litex/soc/misoc/software/bios/linker.ld b/litex/soc/software/bios/linker.ld similarity index 100% rename from litex/soc/misoc/software/bios/linker.ld rename to litex/soc/software/bios/linker.ld diff --git a/litex/soc/misoc/software/bios/main.c b/litex/soc/software/bios/main.c similarity index 99% rename from litex/soc/misoc/software/bios/main.c rename to litex/soc/software/bios/main.c index 0da623ad..0deb9e90 100644 --- a/litex/soc/misoc/software/bios/main.c +++ b/litex/soc/software/bios/main.c @@ -309,7 +309,7 @@ static void dfs(char *baseaddr) static void help(void) { - puts("MiSoC BIOS"); + puts("LiteX SoC BIOS"); puts("Available commands:"); puts("mr - read address space"); puts("mw - write address space"); @@ -533,7 +533,8 @@ int main(int i, char **c) irq_setmask(0); irq_setie(1); uart_init(); - puts("\nMiSoC BIOS\n" + puts("\nLiteX SoC BIOS\n" + "(c) Copyright 2015 Enjoy-Digital\n" "(c) Copyright 2007-2015 M-Labs Limited\n" "Built "__DATE__" "__TIME__"\n"); crcbios(); diff --git a/litex/soc/misoc/software/bios/sdram.c b/litex/soc/software/bios/sdram.c similarity index 100% rename from litex/soc/misoc/software/bios/sdram.c rename to litex/soc/software/bios/sdram.c diff --git a/litex/soc/misoc/software/bios/sdram.h b/litex/soc/software/bios/sdram.h similarity index 100% rename from litex/soc/misoc/software/bios/sdram.h rename to litex/soc/software/bios/sdram.h diff --git a/litex/soc/misoc/software/bios/sfl.h b/litex/soc/software/bios/sfl.h similarity index 100% rename from litex/soc/misoc/software/bios/sfl.h rename to litex/soc/software/bios/sfl.h diff --git a/litex/soc/misoc/software/common.mak b/litex/soc/software/common.mak similarity index 84% rename from litex/soc/misoc/software/common.mak rename to litex/soc/software/common.mak index da127a1d..accbfe9d 100644 --- a/litex/soc/misoc/software/common.mak +++ b/litex/soc/software/common.mak @@ -36,10 +36,10 @@ endif # Toolchain options # -INCLUDES = -I$(MISOC_DIRECTORY)/software/include/base -I$(MISOC_DIRECTORY)/software/include -I$(MISOC_DIRECTORY)/common -I$(BUILDINC_DIRECTORY) +INCLUDES = -I$(SOC_DIRECTORY)/software/include/base -I$(SOC_DIRECTORY)/software/include -I$(SOC_DIRECTORY)/common -I$(BUILDINC_DIRECTORY) COMMONFLAGS = -Os $(CPUFLAGS) -fomit-frame-pointer -Wall -fno-builtin -nostdinc $(INCLUDES) CFLAGS = $(COMMONFLAGS) -fexceptions -Wstrict-prototypes -Wold-style-definition -Wmissing-prototypes -CXXFLAGS = $(COMMONFLAGS) -std=c++11 -I$(MISOC_DIRECTORY)/software/include/basec++ -fexceptions -fno-rtti -ffreestanding +CXXFLAGS = $(COMMONFLAGS) -std=c++11 -I$(SOC_DIRECTORY)/software/include/basec++ -fexceptions -fno-rtti -ffreestanding LDFLAGS = -nostdlib -nodefaultlibs -L$(BUILDINC_DIRECTORY) # compile and generate dependencies, based on diff --git a/litex/soc/software/compiler_rt b/litex/soc/software/compiler_rt new file mode 160000 index 00000000..81fb4f00 --- /dev/null +++ b/litex/soc/software/compiler_rt @@ -0,0 +1 @@ +Subproject commit 81fb4f00c2cfe13814765968e09931ffa93b5138 diff --git a/litex/soc/misoc/software/include/base/assert.h b/litex/soc/software/include/base/assert.h similarity index 100% rename from litex/soc/misoc/software/include/base/assert.h rename to litex/soc/software/include/base/assert.h diff --git a/litex/soc/misoc/software/include/base/console.h b/litex/soc/software/include/base/console.h similarity index 100% rename from litex/soc/misoc/software/include/base/console.h rename to litex/soc/software/include/base/console.h diff --git a/litex/soc/misoc/software/include/base/crc.h b/litex/soc/software/include/base/crc.h similarity index 100% rename from litex/soc/misoc/software/include/base/crc.h rename to litex/soc/software/include/base/crc.h diff --git a/litex/soc/misoc/software/include/base/ctype.h b/litex/soc/software/include/base/ctype.h similarity index 100% rename from litex/soc/misoc/software/include/base/ctype.h rename to litex/soc/software/include/base/ctype.h diff --git a/litex/soc/misoc/software/include/base/endian.h b/litex/soc/software/include/base/endian.h similarity index 100% rename from litex/soc/misoc/software/include/base/endian.h rename to litex/soc/software/include/base/endian.h diff --git a/litex/soc/misoc/software/include/base/errno.h b/litex/soc/software/include/base/errno.h similarity index 100% rename from litex/soc/misoc/software/include/base/errno.h rename to litex/soc/software/include/base/errno.h diff --git a/litex/soc/misoc/software/include/base/float.h b/litex/soc/software/include/base/float.h similarity index 100% rename from litex/soc/misoc/software/include/base/float.h rename to litex/soc/software/include/base/float.h diff --git a/litex/soc/misoc/software/include/base/id.h b/litex/soc/software/include/base/id.h similarity index 100% rename from litex/soc/misoc/software/include/base/id.h rename to litex/soc/software/include/base/id.h diff --git a/litex/soc/misoc/software/include/base/inttypes.h b/litex/soc/software/include/base/inttypes.h similarity index 100% rename from litex/soc/misoc/software/include/base/inttypes.h rename to litex/soc/software/include/base/inttypes.h diff --git a/litex/soc/misoc/software/include/base/irq.h b/litex/soc/software/include/base/irq.h similarity index 100% rename from litex/soc/misoc/software/include/base/irq.h rename to litex/soc/software/include/base/irq.h diff --git a/litex/soc/misoc/software/include/base/limits.h b/litex/soc/software/include/base/limits.h similarity index 100% rename from litex/soc/misoc/software/include/base/limits.h rename to litex/soc/software/include/base/limits.h diff --git a/litex/soc/misoc/software/include/base/pthread.h b/litex/soc/software/include/base/pthread.h similarity index 100% rename from litex/soc/misoc/software/include/base/pthread.h rename to litex/soc/software/include/base/pthread.h diff --git a/litex/soc/misoc/software/include/base/spiflash.h b/litex/soc/software/include/base/spiflash.h similarity index 100% rename from litex/soc/misoc/software/include/base/spiflash.h rename to litex/soc/software/include/base/spiflash.h diff --git a/litex/soc/misoc/software/include/base/spr-defs.h b/litex/soc/software/include/base/spr-defs.h similarity index 100% rename from litex/soc/misoc/software/include/base/spr-defs.h rename to litex/soc/software/include/base/spr-defs.h diff --git a/litex/soc/misoc/software/include/base/stdarg.h b/litex/soc/software/include/base/stdarg.h similarity index 100% rename from litex/soc/misoc/software/include/base/stdarg.h rename to litex/soc/software/include/base/stdarg.h diff --git a/litex/soc/misoc/software/include/base/stdbool.h b/litex/soc/software/include/base/stdbool.h similarity index 100% rename from litex/soc/misoc/software/include/base/stdbool.h rename to litex/soc/software/include/base/stdbool.h diff --git a/litex/soc/misoc/software/include/base/stddef.h b/litex/soc/software/include/base/stddef.h similarity index 100% rename from litex/soc/misoc/software/include/base/stddef.h rename to litex/soc/software/include/base/stddef.h diff --git a/litex/soc/misoc/software/include/base/stdint.h b/litex/soc/software/include/base/stdint.h similarity index 100% rename from litex/soc/misoc/software/include/base/stdint.h rename to litex/soc/software/include/base/stdint.h diff --git a/litex/soc/misoc/software/include/base/stdio.h b/litex/soc/software/include/base/stdio.h similarity index 100% rename from litex/soc/misoc/software/include/base/stdio.h rename to litex/soc/software/include/base/stdio.h diff --git a/litex/soc/misoc/software/include/base/stdlib.h b/litex/soc/software/include/base/stdlib.h similarity index 100% rename from litex/soc/misoc/software/include/base/stdlib.h rename to litex/soc/software/include/base/stdlib.h diff --git a/litex/soc/misoc/software/include/base/string.h b/litex/soc/software/include/base/string.h similarity index 100% rename from litex/soc/misoc/software/include/base/string.h rename to litex/soc/software/include/base/string.h diff --git a/litex/soc/misoc/software/include/base/system.h b/litex/soc/software/include/base/system.h similarity index 100% rename from litex/soc/misoc/software/include/base/system.h rename to litex/soc/software/include/base/system.h diff --git a/litex/soc/misoc/software/include/base/time.h b/litex/soc/software/include/base/time.h similarity index 100% rename from litex/soc/misoc/software/include/base/time.h rename to litex/soc/software/include/base/time.h diff --git a/litex/soc/misoc/software/include/base/uart.h b/litex/soc/software/include/base/uart.h similarity index 100% rename from litex/soc/misoc/software/include/base/uart.h rename to litex/soc/software/include/base/uart.h diff --git a/litex/soc/misoc/software/include/basec++/algorithm b/litex/soc/software/include/basec++/algorithm similarity index 100% rename from litex/soc/misoc/software/include/basec++/algorithm rename to litex/soc/software/include/basec++/algorithm diff --git a/litex/soc/misoc/software/include/basec++/cstddef b/litex/soc/software/include/basec++/cstddef similarity index 100% rename from litex/soc/misoc/software/include/basec++/cstddef rename to litex/soc/software/include/basec++/cstddef diff --git a/litex/soc/misoc/software/include/basec++/cstdlib b/litex/soc/software/include/basec++/cstdlib similarity index 100% rename from litex/soc/misoc/software/include/basec++/cstdlib rename to litex/soc/software/include/basec++/cstdlib diff --git a/litex/soc/misoc/software/include/basec++/new b/litex/soc/software/include/basec++/new similarity index 100% rename from litex/soc/misoc/software/include/basec++/new rename to litex/soc/software/include/basec++/new diff --git a/litex/soc/misoc/software/include/dyld/dlfcn.h b/litex/soc/software/include/dyld/dlfcn.h similarity index 100% rename from litex/soc/misoc/software/include/dyld/dlfcn.h rename to litex/soc/software/include/dyld/dlfcn.h diff --git a/litex/soc/misoc/software/include/dyld/dyld.h b/litex/soc/software/include/dyld/dyld.h similarity index 100% rename from litex/soc/misoc/software/include/dyld/dyld.h rename to litex/soc/software/include/dyld/dyld.h diff --git a/litex/soc/misoc/software/include/dyld/elf.h b/litex/soc/software/include/dyld/elf.h similarity index 100% rename from litex/soc/misoc/software/include/dyld/elf.h rename to litex/soc/software/include/dyld/elf.h diff --git a/litex/soc/misoc/software/include/dyld/link.h b/litex/soc/software/include/dyld/link.h similarity index 100% rename from litex/soc/misoc/software/include/dyld/link.h rename to litex/soc/software/include/dyld/link.h diff --git a/litex/soc/misoc/software/include/hw/common.h b/litex/soc/software/include/hw/common.h similarity index 100% rename from litex/soc/misoc/software/include/hw/common.h rename to litex/soc/software/include/hw/common.h diff --git a/litex/soc/misoc/software/include/hw/ethmac_mem.h b/litex/soc/software/include/hw/ethmac_mem.h similarity index 100% rename from litex/soc/misoc/software/include/hw/ethmac_mem.h rename to litex/soc/software/include/hw/ethmac_mem.h diff --git a/litex/soc/misoc/software/include/hw/flags.h b/litex/soc/software/include/hw/flags.h similarity index 100% rename from litex/soc/misoc/software/include/hw/flags.h rename to litex/soc/software/include/hw/flags.h diff --git a/litex/soc/misoc/software/include/net/microudp.h b/litex/soc/software/include/net/microudp.h similarity index 100% rename from litex/soc/misoc/software/include/net/microudp.h rename to litex/soc/software/include/net/microudp.h diff --git a/litex/soc/misoc/software/include/net/tftp.h b/litex/soc/software/include/net/tftp.h similarity index 100% rename from litex/soc/misoc/software/include/net/tftp.h rename to litex/soc/software/include/net/tftp.h diff --git a/litex/soc/misoc/software/libbase/Makefile b/litex/soc/software/libbase/Makefile similarity index 93% rename from litex/soc/misoc/software/libbase/Makefile rename to litex/soc/software/libbase/Makefile index ade4b3ca..be6d6a7a 100644 --- a/litex/soc/misoc/software/libbase/Makefile +++ b/litex/soc/software/libbase/Makefile @@ -1,5 +1,5 @@ include ../include/generated/variables.mak -include $(MISOC_DIRECTORY)/software/common.mak +include $(SOC_DIRECTORY)/software/common.mak OBJECTS=exception.o libc.o errno.o crc16.o crc32.o console.o system.o id.o uart.o time.o qsort.o strtod.o spiflash.o diff --git a/litex/soc/misoc/software/libbase/console.c b/litex/soc/software/libbase/console.c similarity index 100% rename from litex/soc/misoc/software/libbase/console.c rename to litex/soc/software/libbase/console.c diff --git a/litex/soc/misoc/software/libbase/crc16.c b/litex/soc/software/libbase/crc16.c similarity index 100% rename from litex/soc/misoc/software/libbase/crc16.c rename to litex/soc/software/libbase/crc16.c diff --git a/litex/soc/misoc/software/libbase/crc32.c b/litex/soc/software/libbase/crc32.c similarity index 100% rename from litex/soc/misoc/software/libbase/crc32.c rename to litex/soc/software/libbase/crc32.c diff --git a/litex/soc/misoc/software/libbase/crt0-lm32.S b/litex/soc/software/libbase/crt0-lm32.S similarity index 100% rename from litex/soc/misoc/software/libbase/crt0-lm32.S rename to litex/soc/software/libbase/crt0-lm32.S diff --git a/litex/soc/misoc/software/libbase/crt0-or1k.S b/litex/soc/software/libbase/crt0-or1k.S similarity index 100% rename from litex/soc/misoc/software/libbase/crt0-or1k.S rename to litex/soc/software/libbase/crt0-or1k.S diff --git a/litex/soc/misoc/software/libbase/errno.c b/litex/soc/software/libbase/errno.c similarity index 100% rename from litex/soc/misoc/software/libbase/errno.c rename to litex/soc/software/libbase/errno.c diff --git a/litex/soc/misoc/software/libbase/exception.c b/litex/soc/software/libbase/exception.c similarity index 100% rename from litex/soc/misoc/software/libbase/exception.c rename to litex/soc/software/libbase/exception.c diff --git a/litex/soc/misoc/software/libbase/id.c b/litex/soc/software/libbase/id.c similarity index 75% rename from litex/soc/misoc/software/libbase/id.c rename to litex/soc/software/libbase/id.c index 034ddfa5..863912ab 100644 --- a/litex/soc/misoc/software/libbase/id.c +++ b/litex/soc/software/libbase/id.c @@ -16,5 +16,5 @@ void id_print(void) char sysid[3]; get_sysid_formatted(sysid); - printf("Running on MiSoC (sysid:%s) at %dMHz\n", sysid, identifier_frequency_read()/1000000); + printf("Running on LiteX SoC (sysid:%s) at %dMHz\n", sysid, identifier_frequency_read()/1000000); } diff --git a/litex/soc/misoc/software/libbase/libc.c b/litex/soc/software/libbase/libc.c similarity index 100% rename from litex/soc/misoc/software/libbase/libc.c rename to litex/soc/software/libbase/libc.c diff --git a/litex/soc/misoc/software/libbase/linker-sdram.ld b/litex/soc/software/libbase/linker-sdram.ld similarity index 100% rename from litex/soc/misoc/software/libbase/linker-sdram.ld rename to litex/soc/software/libbase/linker-sdram.ld diff --git a/litex/soc/misoc/software/libbase/qsort.c b/litex/soc/software/libbase/qsort.c similarity index 100% rename from litex/soc/misoc/software/libbase/qsort.c rename to litex/soc/software/libbase/qsort.c diff --git a/litex/soc/misoc/software/libbase/spiflash.c b/litex/soc/software/libbase/spiflash.c similarity index 100% rename from litex/soc/misoc/software/libbase/spiflash.c rename to litex/soc/software/libbase/spiflash.c diff --git a/litex/soc/misoc/software/libbase/strtod.c b/litex/soc/software/libbase/strtod.c similarity index 100% rename from litex/soc/misoc/software/libbase/strtod.c rename to litex/soc/software/libbase/strtod.c diff --git a/litex/soc/misoc/software/libbase/system.c b/litex/soc/software/libbase/system.c similarity index 100% rename from litex/soc/misoc/software/libbase/system.c rename to litex/soc/software/libbase/system.c diff --git a/litex/soc/misoc/software/libbase/time.c b/litex/soc/software/libbase/time.c similarity index 100% rename from litex/soc/misoc/software/libbase/time.c rename to litex/soc/software/libbase/time.c diff --git a/litex/soc/misoc/software/libbase/uart.c b/litex/soc/software/libbase/uart.c similarity index 100% rename from litex/soc/misoc/software/libbase/uart.c rename to litex/soc/software/libbase/uart.c diff --git a/litex/soc/misoc/software/libbase/vsnprintf.c b/litex/soc/software/libbase/vsnprintf.c similarity index 100% rename from litex/soc/misoc/software/libbase/vsnprintf.c rename to litex/soc/software/libbase/vsnprintf.c diff --git a/litex/soc/misoc/software/libcompiler_rt/Makefile b/litex/soc/software/libcompiler_rt/Makefile similarity index 87% rename from litex/soc/misoc/software/libcompiler_rt/Makefile rename to litex/soc/software/libcompiler_rt/Makefile index 6e819b99..f95b80b8 100644 --- a/litex/soc/misoc/software/libcompiler_rt/Makefile +++ b/litex/soc/software/libcompiler_rt/Makefile @@ -1,5 +1,5 @@ include ../include/generated/variables.mak -include $(MISOC_DIRECTORY)/software/common.mak +include $(SOC_DIRECTORY)/software/common.mak CFLAGS+=-D_YUGA_LITTLE_ENDIAN=0 -D_YUGA_BIG_ENDIAN=1 -Wno-missing-prototypes @@ -12,7 +12,7 @@ all: libcompiler_rt.a libcompiler_rt.a: $(OBJECTS) $(AR) crs libcompiler_rt.a $(OBJECTS) -%.o: $(MISOC_DIRECTORY)/software/compiler_rt/lib/builtins/%.c +%.o: $(SOC_DIRECTORY)/software/compiler_rt/lib/builtins/%.c $(compile) .PHONY: all clean diff --git a/litex/soc/misoc/software/libdyld/Makefile b/litex/soc/software/libdyld/Makefile similarity index 75% rename from litex/soc/misoc/software/libdyld/Makefile rename to litex/soc/software/libdyld/Makefile index c378ccdc..d29b53c1 100644 --- a/litex/soc/misoc/software/libdyld/Makefile +++ b/litex/soc/software/libdyld/Makefile @@ -1,5 +1,5 @@ include ../include/generated/variables.mak -include $(MISOC_DIRECTORY)/software/common.mak +include $(SOC_DIRECTORY)/software/common.mak # lm32 is not supported ifeq ($(CPU),lm32) @@ -8,7 +8,7 @@ else ALL_TARGET=libdyld.a endif -COMMONFLAGS += -I$(MISOC_DIRECTORY)/software/include/dyld +COMMONFLAGS += -I$(SOC_DIRECTORY)/software/include/dyld OBJECTS=dyld.o diff --git a/litex/soc/misoc/software/libdyld/dyld.c b/litex/soc/software/libdyld/dyld.c similarity index 100% rename from litex/soc/misoc/software/libdyld/dyld.c rename to litex/soc/software/libdyld/dyld.c diff --git a/litex/soc/misoc/software/libnet/Makefile b/litex/soc/software/libnet/Makefile similarity index 84% rename from litex/soc/misoc/software/libnet/Makefile rename to litex/soc/software/libnet/Makefile index f10feb0d..48a70bc7 100644 --- a/litex/soc/misoc/software/libnet/Makefile +++ b/litex/soc/software/libnet/Makefile @@ -1,5 +1,5 @@ include ../include/generated/variables.mak -include $(MISOC_DIRECTORY)/software/common.mak +include $(SOC_DIRECTORY)/software/common.mak OBJECTS=microudp.o tftp.o diff --git a/litex/soc/misoc/software/libnet/microudp.c b/litex/soc/software/libnet/microudp.c similarity index 100% rename from litex/soc/misoc/software/libnet/microudp.c rename to litex/soc/software/libnet/microudp.c diff --git a/litex/soc/misoc/software/libnet/tftp.c b/litex/soc/software/libnet/tftp.c similarity index 100% rename from litex/soc/misoc/software/libnet/tftp.c rename to litex/soc/software/libnet/tftp.c diff --git a/litex/soc/misoc/software/libunwind/Makefile b/litex/soc/software/libunwind/Makefile similarity index 63% rename from litex/soc/misoc/software/libunwind/Makefile rename to litex/soc/software/libunwind/Makefile index 6ebd8fb1..a1248387 100644 --- a/litex/soc/misoc/software/libunwind/Makefile +++ b/litex/soc/software/libunwind/Makefile @@ -1,5 +1,5 @@ include ../include/generated/variables.mak -include $(MISOC_DIRECTORY)/software/common.mak +include $(SOC_DIRECTORY)/software/common.mak # lm32 is not supported ifeq ($(CPU),lm32) @@ -9,7 +9,7 @@ else endif COMMONFLAGS+=-integrated-as \ - -I. -I$(MISOC_DIRECTORY)/software/include/dyld/ -I$(MISOC_DIRECTORY)/software/unwinder/include/ \ + -I. -I$(SOC_DIRECTORY)/software/include/dyld/ -I$(SOC_DIRECTORY)/software/unwinder/include/ \ -I$(LIBUNWIND_DIRECTORY) \ -D__ELF__ -D__linux__ -D_LIBUNWIND_NO_HEAP -DNDEBUG @@ -20,13 +20,13 @@ all: $(ALL_TARGET) libunwind.a: $(OBJECTS) $(AR) crs libunwind.a $(OBJECTS) -%.o: $(MISOC_DIRECTORY)/software/unwinder/src/%.cpp +%.o: $(SOC_DIRECTORY)/software/unwinder/src/%.cpp $(compilexx) -%.o: $(MISOC_DIRECTORY)/software/unwinder/src/%.c +%.o: $(SOC_DIRECTORY)/software/unwinder/src/%.c $(compile) -%.o: $(MISOC_DIRECTORY)/software/unwinder/src/%.S +%.o: $(SOC_DIRECTORY)/software/unwinder/src/%.S $(assemble) .PHONY: clean diff --git a/litex/soc/misoc/software/libunwind/__cxxabi_config.h b/litex/soc/software/libunwind/__cxxabi_config.h similarity index 100% rename from litex/soc/misoc/software/libunwind/__cxxabi_config.h rename to litex/soc/software/libunwind/__cxxabi_config.h diff --git a/litex/soc/misoc/software/memtest/Makefile b/litex/soc/software/memtest/Makefile similarity index 100% rename from litex/soc/misoc/software/memtest/Makefile rename to litex/soc/software/memtest/Makefile diff --git a/litex/soc/misoc/software/memtest/isr.c b/litex/soc/software/memtest/isr.c similarity index 100% rename from litex/soc/misoc/software/memtest/isr.c rename to litex/soc/software/memtest/isr.c diff --git a/litex/soc/misoc/software/memtest/main.c b/litex/soc/software/memtest/main.c similarity index 100% rename from litex/soc/misoc/software/memtest/main.c rename to litex/soc/software/memtest/main.c diff --git a/litex/soc/software/unwinder b/litex/soc/software/unwinder new file mode 160000 index 00000000..8b119669 --- /dev/null +++ b/litex/soc/software/unwinder @@ -0,0 +1 @@ +Subproject commit 8b1196692d823a090a9879a695050baa7acc39ee diff --git a/migen/build/platforms/__init__.py b/litex/soc/tools/__init__.py similarity index 100% rename from migen/build/platforms/__init__.py rename to litex/soc/tools/__init__.py diff --git a/litex/soc/misoc/tools/flterm.py b/litex/soc/tools/flterm.py similarity index 100% rename from litex/soc/misoc/tools/flterm.py rename to litex/soc/tools/flterm.py diff --git a/litex/soc/misoc/tools/mkmscimg.py b/litex/soc/tools/mkmscimg.py similarity index 100% rename from litex/soc/misoc/tools/mkmscimg.py rename to litex/soc/tools/mkmscimg.py diff --git a/migen/__init__.py b/migen/__init__.py deleted file mode 100644 index 492117f2..00000000 --- a/migen/__init__.py +++ /dev/null @@ -1,10 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import * -from migen.fhdl.specials import * -from migen.fhdl.bitcontainer import * -from migen.fhdl.decorators import * - -from migen.sim import * - -from migen.genlib.record import * -from migen.genlib.fsm import * diff --git a/migen/build/altera/__init__.py b/migen/build/altera/__init__.py deleted file mode 100644 index 9fc45d4a..00000000 --- a/migen/build/altera/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from migen.build.altera.platform import AlteraPlatform -from migen.build.altera.programmer import USBBlaster diff --git a/migen/build/altera/common.py b/migen/build/altera/common.py deleted file mode 100644 index fafb4983..00000000 --- a/migen/build/altera/common.py +++ /dev/null @@ -1,39 +0,0 @@ -from migen.fhdl.module import Module -from migen.fhdl.specials import Instance -from migen.genlib.io import DifferentialInput, DifferentialOutput - - -class AlteraDifferentialInputImpl(Module): - def __init__(self, i_p, i_n, o): - self.specials += Instance("ALT_INBUF_DIFF", - name="ibuf_diff", - i_i=i_p, - i_ibar=i_n, - o_o=o) - - -class AlteraDifferentialInput: - @staticmethod - def lower(dr): - return AlteraDifferentialInputImpl(dr.i_p, dr.i_n, dr.o) - - -class AlteraDifferentialOutputImpl(Module): - def __init__(self, i, o_p, o_n): - self.specials += Instance("ALT_OUTBUF_DIFF", - name="obuf_diff", - i_i=i, - o_o=o_p, - o_obar=o_n) - - -class AlteraDifferentialOutput: - @staticmethod - def lower(dr): - return AlteraDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n) - - -altera_special_overrides = { - DifferentialInput: AlteraDifferentialInput, - DifferentialOutput: AlteraDifferentialOutput -} diff --git a/migen/build/altera/quartus.py b/migen/build/altera/quartus.py deleted file mode 100644 index 99f6e978..00000000 --- a/migen/build/altera/quartus.py +++ /dev/null @@ -1,151 +0,0 @@ -# This file is Copyright (c) 2013 Florent Kermarrec -# License: BSD - -import os -import subprocess - -from migen.fhdl.structure import _Fragment - -from migen.build.generic_platform import Pins, IOStandard, Misc -from migen.build import tools - - -def _format_constraint(c, signame, fmt_r): - if isinstance(c, Pins): - return "set_location_assignment -comment \"{name}\" " \ - "-to {signame} Pin_{pin}".format( - signame=signame, - name=fmt_r, - pin=c.identifiers[0]) - elif isinstance(c, IOStandard): - return "set_instance_assignment -name io_standard " \ - "-comment \"{name}\" \"{std}\" -to {signame}".format( - signame=signame, - name=fmt_r, - std=c.name) - elif isinstance(c, Misc): - if not isinstance(c.misc, str) and len(c.misc) == 2: - return "set_instance_assignment -comment \"{name}\" " \ - "-name {misc[0]} \"{misc[1]}\" -to {signame}".format( - signame=signame, - name=fmt_r, - misc=c.misc) - else: - return "set_instance_assignment -comment \"{name}\" " \ - "-name {misc} " \ - "-to {signame}".format( - signame=signame, - name=fmt_r, - misc=c.misc) - - -def _format_qsf(signame, pin, others, resname): - fmt_r = "{}:{}".format(*resname[:2]) - if resname[2] is not None: - fmt_r += "." + resname[2] - - fmt_c = [_format_constraint(c, signame, fmt_r) for c in - ([Pins(pin)] + others)] - - return '\n'.join(fmt_c) - - -def _build_qsf(named_sc, named_pc): - lines = [] - for sig, pins, others, resname in named_sc: - if len(pins) > 1: - for i, p in enumerate(pins): - lines.append( - _format_qsf("{}[{}]".format(sig, i), p, others, resname)) - else: - lines.append(_format_qsf(sig, pins[0], others, resname)) - - if named_pc: - lines.append("") - lines.append("\n\n".join(named_pc)) - - lines.append("set_global_assignment -name top_level_entity top") - return "\n".join(lines) - - -def _build_files(device, sources, vincpaths, named_sc, named_pc, build_name): - lines = [] - for filename, language, library in sources: - # Enforce use of SystemVerilog - # (Quartus does not support global parameters in Verilog) - if language == "verilog": - language = "systemverilog" - lines.append( - "set_global_assignment -name {lang}_FILE {path} " - "-library {lib}".format( - lang=language.upper(), - path=filename.replace("\\", "/"), - lib=library)) - - for path in vincpaths: - lines.append("set_global_assignment -name SEARCH_PATH {}".format( - path.replace("\\", "/"))) - - lines.append(_build_qsf(named_sc, named_pc)) - lines.append("set_global_assignment -name DEVICE {}".format(device)) - tools.write_to_file("{}.qsf".format(build_name), "\n".join(lines)) - - -def _run_quartus(build_name, quartus_path): - build_script_contents = """# Autogenerated by Migen - -set -e - -quartus_map --read_settings_files=on --write_settings_files=off {build_name} -c {build_name} -quartus_fit --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} -quartus_asm --read_settings_files=off --write_settings_files=off {build_name} -c {build_name} -quartus_sta {build_name} -c {build_name} - -""".format(build_name=build_name) # noqa - build_script_file = "build_" + build_name + ".sh" - tools.write_to_file(build_script_file, - build_script_contents, - force_unix=True) - - if subprocess.call(["bash", build_script_file]): - raise OSError("Subprocess failed") - - -class AlteraQuartusToolchain: - def build(self, platform, fragment, build_dir="build", build_name="top", - toolchain_path="/opt/Altera", run=True): - tools.mkdir_noerror(build_dir) - os.chdir(build_dir) - - if not isinstance(fragment, _Fragment): - fragment = fragment.get_fragment() - platform.finalize(fragment) - - v_output = platform.get_verilog(fragment) - named_sc, named_pc = platform.resolve_signals(v_output.ns) - v_file = build_name + ".v" - v_output.write(v_file) - sources = platform.sources | {(v_file, "verilog", "work")} - _build_files(platform.device, - sources, - platform.verilog_include_paths, - named_sc, - named_pc, - build_name) - if run: - _run_quartus(build_name, toolchain_path) - - os.chdir("..") - - return v_output.ns - - def add_period_constraint(self, platform, clk, period): - # TODO: handle differential clk - platform.add_platform_command( - "set_global_assignment -name duty_cycle 50 -section_id {clk}", - clk=clk) - platform.add_platform_command( - "set_global_assignment -name fmax_requirement \"{freq} MHz\" " - "-section_id {clk}".format(freq=(1. / period) * 1000, - clk="{clk}"), - clk=clk) diff --git a/migen/build/fpgalink_programmer.py b/migen/build/fpgalink_programmer.py deleted file mode 100644 index fc7586dc..00000000 --- a/migen/build/fpgalink_programmer.py +++ /dev/null @@ -1,102 +0,0 @@ -import os - -from migen.build.generic_programmer import GenericProgrammer -from migen.build.xilinx.programmer import _create_xsvf - -try: - import fl -except ImportError: - import fpgalink3 as fl - -fl.flInitialise(0) - - -class FPGALink(GenericProgrammer): - """Using the fpgalink library from makestuff - - You will need fpgalink library installed from - https://github.com/makestuff/libfpgalink - """ - - needs_bitreverse = False - - def __init__(self, initial_vidpid=None, pin_cfg="D0D2D3D4", - fpgalink_vidpid="1D50:602B:0002", flash_proxy_basename=None): - """ - Parameters - ---------- - initial_vidpid : string - The USB vendor and product id of the device before fpgalink - firmware is loaded onto the device. - - Format is vid:pid as 4 digit hex numbers. - - pin_cfg : string - FPGALink pin configuration string describing how the JTAG interface - is hooked up to the programmer. - - fpgalink_vidpid : string - The USB vendor, product and device id of the device after the - fpgalink firmware is loaded onto the device. - - Format is vid:pid:did as 4 digit hex numbers. - Defaults to 1D50:602B:0002 which is the makestuff FPGALink device. - """ - GenericProgrammer.__init__(self, flash_proxy_basename) - self.initial_vidpid = initial_vidpid - self.fpgalink_vidpid = fpgalink_vidpid - self.pin_cfg = pin_cfg - - def open_device(self): - ivp = self.initial_vidpid - vp = self.fpgalink_vidpid - - print("Attempting to open connection to FPGALink device", vp, "...") - try: - handle = fl.flOpen(self.fpgalink_vidpid) - except fl.FLException as ex: - if not ivp: - raise FLException( - "Could not open FPGALink device at {0} and" - " no initial VID:PID was supplied".format(vp)) - - print("Loading firmware into %s..." % ivp) - fl.flLoadStandardFirmware(ivp, vp) - - print("Awaiting renumeration...") - if not fl.flAwaitDevice(vp, 600): - raise fl.FLException( - "FPGALink device did not renumerate properly" - " as {0}".format(vp)) - - print("Attempting to open connection to FPGALink device", vp, - "again...") - handle = fl.flOpen(vp) - - # Only Nero capable hardware support doing programming. - assert fl.flIsNeroCapable(handle) - print("Cable connection opened.") - return handle - - def load_bitstream(self, bitstream_file): - n = 27 - - xsvf_file = os.path.splitext(bitstream_file)[0]+'.xsvf' - print("\nGenerating xsvf formatted bitstream") - print("="*n) - if os.path.exists(xsvf_file): - os.unlink(xsvf_file) - _create_xsvf(bitstream_file, xsvf_file) - print("\n"+"="*n+"\n") - - print("Programming %s to device." % xsvf_file) - print("="*n) - handle = self.open_device() - print("Programming device...") - fl.flProgram(handle, "J:"+self.pin_cfg, progFile=xsvf_file) - print("Programming successful!") - print("="*n+"\n") - fl.flClose(handle) - - def flash(self, address, data_file): - raise NotImplementedError("Not supported yet.") diff --git a/migen/build/generic_programmer.py b/migen/build/generic_programmer.py deleted file mode 100644 index 82a1ebe0..00000000 --- a/migen/build/generic_programmer.py +++ /dev/null @@ -1,31 +0,0 @@ -import os - - -class GenericProgrammer: - def __init__(self, flash_proxy_basename=None): - self.flash_proxy_basename = flash_proxy_basename - self.flash_proxy_dirs = [ - "~/.migen", "/usr/local/share/migen", "/usr/share/migen", - "~/.mlabs", "/usr/local/share/mlabs", "/usr/share/mlabs"] - - def set_flash_proxy_dir(self, flash_proxy_dir): - if flash_proxy_dir is not None: - self.flash_proxy_dirs = [flash_proxy_dir] - - def find_flash_proxy(self): - for d in self.flash_proxy_dirs: - fulldir = os.path.abspath(os.path.expanduser(d)) - fullname = os.path.join(fulldir, self.flash_proxy_basename) - if os.path.exists(fullname): - return fullname - raise OSError("Failed to find flash proxy bitstream") - - # must be overloaded by specific programmer - def load_bitstream(self, bitstream_file): - raise NotImplementedError - - # must be overloaded by specific programmer - def flash(self, address, data_file): - raise NotImplementedError - - diff --git a/migen/build/lattice/__init__.py b/migen/build/lattice/__init__.py deleted file mode 100644 index 78b2035d..00000000 --- a/migen/build/lattice/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from migen.build.lattice.platform import LatticePlatform -from migen.build.lattice.programmer import LatticeProgrammer diff --git a/migen/build/lattice/common.py b/migen/build/lattice/common.py deleted file mode 100644 index c25e8b90..00000000 --- a/migen/build/lattice/common.py +++ /dev/null @@ -1,41 +0,0 @@ -from migen.fhdl.module import Module -from migen.fhdl.specials import Instance -from migen.genlib.io import * -from migen.genlib.resetsync import AsyncResetSynchronizer - - -class LatticeAsyncResetSynchronizerImpl(Module): - def __init__(self, cd, async_reset): - rst1 = Signal() - self.specials += [ - Instance("FD1S3BX", i_D=0, i_PD=async_reset, - i_CK=cd.clk, o_Q=rst1), - Instance("FD1S3BX", i_D=rst1, i_PD=async_reset, - i_CK=cd.clk, o_Q=cd.rst) - ] - - -class LatticeAsyncResetSynchronizer: - @staticmethod - def lower(dr): - return LatticeAsyncResetSynchronizerImpl(dr.cd, dr.async_reset) - - -class LatticeDDROutputImpl(Module): - def __init__(self, i1, i2, o, clk): - self.specials += Instance("ODDRXD1", - synthesis_directive="ODDRAPPS=\"SCLK_ALIGNED\"", - i_SCLK=clk, - i_DA=i1, i_DB=i2, o_Q=o, - ) - - -class LatticeDDROutput: - @staticmethod - def lower(dr): - return LatticeDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk) - -lattice_special_overrides = { - AsyncResetSynchronizer: LatticeAsyncResetSynchronizer, - DDROutput: LatticeDDROutput -} diff --git a/migen/build/lattice/programmer.py b/migen/build/lattice/programmer.py deleted file mode 100644 index cc3c50bd..00000000 --- a/migen/build/lattice/programmer.py +++ /dev/null @@ -1,54 +0,0 @@ -import os -import subprocess - -from migen.build.generic_programmer import GenericProgrammer -from migen.build import tools - - -# XXX Lattice programmer need an .xcf file, will need clean up and support for more parameters -_xcf_template = """ - - - - - - JTAG - - - 1 - Lattice - LatticeECP3 - LFE3-35EA - {bitstream_file} - Fast Program - - - - SEQUENTIAL - ENTIRED CHAIN - No Override - TLR - TLR - - - - USB2 - FTUSB-0 - Dual RS232-HS A Location 0000 Serial A - - TRST ABSENT; - ISPEN ABSENT; - - - -""" - - -class LatticeProgrammer(GenericProgrammer): - needs_bitreverse = False - - def load_bitstream(self, bitstream_file): - xcf_file = bitstream_file.replace(".bit", ".xcf") - xcf_content = _xcf_template.format(bitstream_file=bitstream_file) - tools.write_to_file(xcf_file, xcf_content) - subprocess.call(["pgrcmd", "-infile", xcf_file]) diff --git a/migen/build/openocd.py b/migen/build/openocd.py deleted file mode 100644 index aec29980..00000000 --- a/migen/build/openocd.py +++ /dev/null @@ -1,30 +0,0 @@ -import subprocess - -from migen.build.generic_programmer import GenericProgrammer - - -class OpenOCD(GenericProgrammer): - needs_bitreverse = False - - def __init__(self, config, flash_proxy_basename=None): - GenericProgrammer.__init__(self, flash_proxy_basename) - self.config = config - - def load_bitstream(self, bitstream): - script = "; ".join([ - "init", - "pld load 0 {}".format(bitstream), - "exit", - ]) - subprocess.call(["openocd", "-f", self.config, "-c", script]) - - def flash(self, address, data): - flash_proxy = self.find_flash_proxy() - script = "; ".join([ - "init", - "jtagspi_init 0 {}".format(flash_proxy), - "jtagspi_program {} 0x{:x}".format(data, address), - "fpga_program", - "exit" - ]) - subprocess.call(["openocd", "-f", self.config, "-c", script]) diff --git a/migen/build/platforms/apf27.py b/migen/build/platforms/apf27.py deleted file mode 100644 index ea182e21..00000000 --- a/migen/build/platforms/apf27.py +++ /dev/null @@ -1,150 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_ios = [ - ("clk0", 0, Pins("N9"), IOStandard("LVCMOS18")), - ("fpga_reset", 0, Pins("T9"), IOStandard("LVCMOS18"), Drive("8")), - ("fpga_initb", 0, Pins("T12"), IOStandard("LVCMOS18"), Drive("8")), - ("weim", 0, - Subsignal("cs4_dtack", Pins("R3"), IOStandard("LVCMOS18"), Drive("8")), - Subsignal("cs5n", Pins("P10"), IOStandard("LVCMOS18")), - Subsignal("eb0n", Pins("P9"), IOStandard("LVCMOS18")), - Subsignal("oen", Pins("R9"), IOStandard("LVCMOS18")), - Subsignal("data", - Pins("T5 T6 P7 N8 P12 T13 R13 T14 P5 N6 T3 T11 T4 R5 M10 T10"), - IOStandard("LVCMOS18"), Drive("8")), - Subsignal("addr", - Pins("N5 L7 M7 M8 L8 L9 L10 M11 P11 N11 N12 P13"), - IOStandard("LVCMOS18")) - ) -] - -_connectors = [ - ("J2", - "None", # no 0 pin - "None", # 1 +3v3 - "None", # 2 +3v3 - "None", # 3 GND - "None", # 4 GND - "None", # 5 DP USB_OTG_PHY +3V3 - "None", # 6 DM USB_OTG_PHY +3V3 - "None", # 7 VBUS USB_OTG_ PHY +3V3 - "None", # 8 PSW_N USB_OTG_PHY +3V3 - "None", # 9 ID USB_OTG_PHY +3V3 - "None", # 10 FAULT USB_OTG_PHY +3V3 - "None", # 11 RXP Ethernet_PHY +3V3 - "None", # 12 RXN Ethernet_PHY +3V3 - "None", # 13 ETH_LINK Ethernet_PHY +2V8 - "None", # 14 PC_VS2 PC +2V8 PF13 - "None", # 15 PC_VS1 PC +2V8 PF14 - "None", # 16 PC_PWRON PC +2V8 PF16 - "None", # 17 PC_READY PC +2V8 PF17 - "None", # 18 PWM0 PWM0 +2V8 PE5 - "None", # 19 TOUT GPT +2V8 PC14 - "None", # 20 GND POWER - "None", # 21 VCC01 (IN) BANK1 SUPPLY VCCO1 - "C16", # 22 IO_L24P_1 FPGA_BANK1 VCC01 - "C15", # 23 IO_L24N_1 FPGA_BANK1 VCC01 - "D16", # 24 IO_L22_P1 FPGA_BANK1 VCC01 - "None", # 25 GND POWER - "B14", # 26 IO_L02N_0 FPGA_BANK0 VCCO0 - "B15", # 27 IO_L02P_0 FPGA_BANK0 - "A13", # 28 IO_L04N_0 FPGA_BANK0 - "A14", # 29 IO_L04P_0 FPGA_BANK0 VCCO0 - "D11", # 30 IO_L03N_0 FPGA_BANK0 VCCO0 - "C12", # 31 IO_L03P_0 FPGA_BANK0 VCCO0 - "A10", # 32 IO_L08N_0 FPGA_BANK0 VCCO0 - "B10", # 33 IO_L08P_0 FPGA_BANK0 VCCO0 - "A9", # 34 IO_L10N_0 / GLCK7 FPGA_BANK0 VCCO0 - "C9", # 35 IO_L10P_0 / GCLK6 FPGA_BANK0 VCCO0 - "B8", # 36 IO_L12N_0 / GCLK11 FPGA_BANK0 VCCO0 - "A8", # 37 IO_L12P_0 / GCLK10 FPGA_BANK0 VCCO0 - "B6", # 38 IO_L15N_0 FPGA_BANK0 VCCO0 - "A6", # 39 IO_L15P_0 FPGA_BANK0 VCCO0 - "B4", # 40 IO_L18N_0 FPGA_BANK0 VCCO0 - "A4", # 41 IO_L18P_0 FPGA_BANK0 VCCO0 - "None", # 42 GND POWER - "N3", # 43 IO_L24P_3 FPGA_BANK3 VCCO3 - "R1", # 44 IO_L23P_3 FPGA_BANK3 VCCO3 - "P1", # 45 IO_L22N_3 FPGA_BANK3 VCCO3 - "N1", # 46 IO_L20N_3 FPGA_BANK3 VCCO3 - "M1", # 47 IO_L20P_3 FPGA_BANK3 VCCO3 - "H3", # 48 IO_L12P_3 FPGA_BANK3 VCCO3 - "K1", # 49 IO_L15N_3 FPGA_BANK3 VCCO3 - "J1", # 50 IO_L14N_3 FPGA_BANK3 VCCO3 - "H1", # 51 IO_L11N_3 FPGA_BANK3 VCCO3 - "G1", # 52 IO_L08N_3 FPGA_BANK3 VCCO3 - "F1", # 53 IO_L08P_3 FPGA_BANK3 VCCO3 - "E1", # 54 IO_L03N_3 FPGA_BANK3 VCCO3 - "D1", # 55 IO_LO3P_3 FPGA_BANK3 VCCO3 - "C1", # 56 IO_L01N_3 FPGA_BANK3 VCCO3 - "None", # 57 GND POWER - "None", # 58 TRSTN JTAG +2V8 - "None", # 59 TDI JTAG +2V8 - "None", # 60 TCK JTAG +2V8 - "None", # 61 TDO JTAG +2V8 - "None", # 62 TMS JTAG +2V8 - "None", # 63 GND POWER - "C2", # 64 IO_L01P_3 FPGA_BANK3 VCCO3 - "D3", # 65 IO_L02N_3 FPGA_BANK3 VCCO3 - "D4", # 66 IO_L02P_3 FPGA_BANK3 VCCO3 - "F4", # 67 IP_LO4N_3 FPGA_BANK3 VCCO3 - "G2", # 68 IO_L11P_3 FPGA_BANK3 VCCO3 - "J2", # 69 IO_L14P_3 FPGA_BANK3 VCCO3 - "K3", # 70 IO_L15P_3 FPGA_BANK3 VCCO3 - "J3", # 71 IO_L12N_3 FPGA_BANK3 VCCO3 - "N2", # 72 IO_L22P_3 FPGA_BANK3 VCCO3 - "P2", # 73 IO_L23N_3 FPGA_BANK3 VCCO3 - "M4", # 74 IO_L24N_3 FPGA_BANK3 VCCO3 - "L6", # 75 IP_L25N_3 FPGA_BANK3 VCCO3 - "None", # 76 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax) - "None", # 77 VCCO3 (IN) BANK3 SUPPLY VCCO3 (3.3Vmax) - "A3", # 78 IO_L19P_0 FPGA_BANK0 VCCO0 - "B3", # 79 IO_L19N_0 FPGA_BANK0 VCCO0 - "A5", # 80 IO_L17P_0 FPGA_BANK0 VCCO0 - "C5", # 81 IO_L17N_0 FPGA_BANK0 VCCO0 - "D7", # 82 IO_L16P_0 FPGA_BANK0 VCCO0 - "C6", # 83 IO_L16N_0 FPGA_BANK0 VCCO0 - "C8", # 84 IO_L11P_0 / GCLK8 FPGA_BANK0 VCCO0 - "D8", # 85 IO_L11N_0 / GCLK9 FPGA_BANK0 VCCO0 - "C10", # 86 IO_L09P_0 / GCLK4 FPGA_BANK0 VCCO0 - "D9", # 87 IO_L09N_0 / GCLK5 FPGA_BANK0 VCCO0 - "C11", # 88 IO_L07P_0 FPGA_BANK0 VCCO0 - "A11", # 89 IO_L07N_0 FPGA_BANK0 VCCO0 - "D13", # 90 IO_L01P_0 FPGA_BANK0 VCCO0 - "C13", # 91 IO_L01N_0 FPGA_BANK0 VCCO0 - "None", # 92 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax) - "None", # 93 VCCO0 (IN) BANK0 SUPPLY VCCO0 (3.3Vmax) - "None", # 94 GND POWER VCCO0 A13 - "D15", # 95 IO_L22N_1 FPGA_BANK1 VCC01 - "E13", # 96 IO_L23P_1 FPGA_BANK1 VCC01 - "D14", # 97 IO_L23N_1 FPGA_BANK1 VCC01 - "E14", # 98 IO_L20P_1 FPGA_BANK1 VCC01 - "F13", # 99 IO_L20N_1 FPGA_BANK1 VCC01 - "None", # 100 GND POWER (3.3Vmax) - "None", # 101 USR_RESETN (open CONFIG Pos PC15 +2V8 drain with pullup) - "None", # 102 TIN GPT +2V8 - "None", # 103 EXTAL_26M CONFIG +2V5 - "None", # 104 RX3 RS232_3 RS232 - "None", # 105 TX3 RS232_3 RS232 - "None", # 106 RX1 RS232_1 RS232 - "None", # 107 TX1 RS232_1 RS232 - "None", # 108 BOOT CONFIG +2V8 - "None", # 109 TXN Ethernet_PHY +3V3 - "None", # 110 TXP Ethernet_PHY +3V3 - "None", # 111 ETH_ACTIVITY Ethernet_PHY +2V8 - "None", # 112 USBH2_NXT USB_HOST2 +2V5 PA3 - "None", # 113 USBH2_DIR USB_HOST2 +2V5 PA1 - "None", # 114 USBH2_DATA7 USB_HOST2 +2V5 PA2 - "None", # 115 USBH2_STP USB_HOST2 +2V5 PA4 - "None") # 116 USBH2_CLK USB_HOST2 +2V5 PA0 -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk0" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc3s200a-ft256-4", _ios, _connectors) diff --git a/migen/build/platforms/apf51.py b/migen/build/platforms/apf51.py deleted file mode 100644 index f776cdac..00000000 --- a/migen/build/platforms/apf51.py +++ /dev/null @@ -1,177 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_ios = [ - ("clk3", 0, Pins("N8"), IOStandard("LVCMOS33")), - ("clko", 0, Pins("N7"), IOStandard("LVCMOS33")), - ("fpga_initb", 0, Pins("P3"), IOStandard("LVCMOS33")), - ("fpga_program", 0, Pins("R2"), IOStandard("LVCMOS33")), - ("eim", 0, - Subsignal("bclk", Pins("N12")), - Subsignal("eb1", Pins("P13")), - Subsignal("cs1", Pins("R11")), - Subsignal("cs2", Pins("N9")), - Subsignal("lba", Pins("R9")), - Subsignal("eb0", Pins("P7")), - Subsignal("oe", Pins("R7")), - Subsignal("rw", Pins("R6")), - Subsignal("dtack", Pins("N4")), - Subsignal("wait", Pins("R4")), - Subsignal("da", Pins("N6 L5 L6 R5 P5 N11 M11 P11 L8 K8 M8 M10 L9 R10 N5 M5")), - IOStandard("LVCMOS33") - ) -] - -_connectors = [ - ("J2", - "None", # No 0 pin - "None", # 1 FPGA Bank1 power - "None", # 2 FPGA Bank1 power - "None", # 3 GND - "B14", # 4 IO_L1P_A25_1 - "B15", # 5 IO_L1N_A24_VREF_1 - "C14", # 6 IO_L33P_A15_M1A10_1 - "C15", # 7 IO_L33N_A14_M1A4_1 - "D13", # 8 IO_L35P_A11_M1A7_1 - "D15", # 9 IO_L35N_A10_M1A2_1 - "E14", # 10 IO_L37P_A7_M1A0_1 - "E15", # 11 IO_L37N_A6_M1A1_1 - "None", # 12 GND - "F13", # 13 IO_L39P_M1A3_1 - "F15", # 14 IO_L39N_M1ODT_1 - "G14", # 15 IO_L41P_GCLK9_IRDY1_M1RASN_1 - "G15", # 16 IO_L41N_GCLK8_M1CASN_1 - "H13", # 17 IO_L42P_GCLK7_M1UDM_1 - "H15", # 18 IO_L42N_GCLK6_TRDY1_M1LDM - "J14", # 19 IO_L43P_GCLK5_M1DQ4_1 - "J15", # 20 IO_L43N_GCLK4_M1DQ5_1 - "K13", # 21 IO_L44P_A3_M1DQ6_1 - "K15", # 22 IO_L44N_A2_M1DQ7_1 - "L14", # 23 IO_L45P_A1_M1LDQS_1 - "L15", # 24 IO_L45N_A0_M1LDQSN_1 - "None", # 25 GND - "E2", # 26 IO_L52P_M3A8_3 - "E1", # 27 IO_L52N_M3A9_3 - "D3", # 28 IO_L54P_M3RESET_3 - "D1", # 29 IO_L54N_M3A11_3 - "F3", # 30 IO_L46P_M3CLK_3 - "F1", # 31 IO_L46N_M3CLKN_3 - "G2", # 32 IO_L44P_GCLK21_M3A5_3 - "G1", # 33 IO_L44N_GCLK20_M3A6_3 - "H3", # 34 IO_L42P_GCLK25_TRDY2_M3UDM_3 - "H1", # 35 IO_L42N_GCLK24_M3LDM_3 - "K3", # 36 IO_L40P_M3DQ6_3 - "K1", # 37 IO_L40N_M3DQ7_3 - "None", # 38 GND - "None", # 39 GPIO4_16 - "None", # 40 GPIO4_17 - "None", # 41 BOOT_MODE0 - "None", # 42 AUD5_RXFS - "None", # 43 AUD5_RXC - "None", # 44 GND - "None", # 45 AUD5_RXD - "None", # 46 AUD5_TXC - "None", # 47 AUD5_TXFS - "None", # 48 GND - "None", # 49 SPI2_SCLK_GPT_CMPOUT3 - "None", # 50 SPI2_MISO - "None", # 51 SPI2_MOSI - "None", # 52 SPI2_SS1 - "None", # 53 SPI2_SS2 - "None", # 54 SPI2_SS3 - "None", # 55 SPI2_RDY - "None", # 56 OWIRE - "None", # 57 GND - "None", # 58 SPI1_SCLK - "None", # 59 SPI1_MISO - "None", # 60 SPI1_MOSI - "None", # 61 SPI1_SS0 - "None", # 62 SPI1_SS1 - "None", # 63 SPI1_RDY - "None", # 64 RESET# - "None", # 65 VIO_H2 - "None", # 66 PMIC_GPIO6 - "None", # 67 TOUCH_X+ - "None", # 68 TOUCH_X- - "None", # 69 TOUCH_Y+ - "None", # 70 TOUCH_Y- - "None", # 71 AUXADCIN4 - "None", # 72 AUXADCIN3 - "None", # 73 AUXADCIN2 - "None", # 74 AUXADCIN1 - "None", # 75 PMIC_GPIO7 - "None", # 76 +1v8 - "None", # 77 RESERVED - "None", # 78 UART3_TXD - "None", # 79 UART_3_RXD - "None", # 80 UART2_TXD - "None", # 81 UART2_RXD - "None", # 82 UART2_RTS_KEY_COL7 - "None", # 83 UART2_CTS_KEY_COL6 - "None", # 84 UART1_TXD - "None", # 85 UART1_RXD - "None", # 86 UART1_RTS - "None", # 87 UART1_CTS - "None", # 88 GND - "None", # 89 AUD3_TXD - "None", # 90 AUD3_RXD - "None", # 91 AUD3_FS - "None", # 92 AUD3_CK - "None", # 93 GND - "None", # 94 AUD6_TXFS_KEY_ROW7 - "None", # 95 AUD6_TXC_KEY_ROW6 - "None", # 96 AUD6_RXD_KEY_ROW5 - "None", # 97 AUD6_TXD_KEY_ROW4 - "None", # 98 I2C2_SDA_UART3_CTS - "None", # 99 I2C2_SCL_UART3_RTS - "None", # 100 BOOT_MODE1 - "None", # 101 PWM2 - "None", # 102 PWM1 - "None", # 103 GND - "L1", # 104 IO_L39N_M3LDQSN_3 - "L2", # 105 IO_L39P_M3LDQS_3 - "J1", # 106 IO_L41N_GCLK26_M3DQ5_3 - "J2", # 107 IO_L41P_GCLK27_M3DQ4_3 - "J3", # 108 IO_L43N_GCLK22_IRDY2_M3CASN_3 - "K4", # 109 IO_L43P_GCLK23_M3RASN_3 - "J4", # 110 IO_L45N_M3ODT_3 - "K5", # 111 IO_L45P_M3A3_3 - "C1", # 112 IO_L83N_VREF_3 - "C2", # 113 IO_L83P_3 - "E3", # 114 IO_L53N_M3A12_3 - "D4", # 115 IO_L53P_M3CKE_3 - "None", # 116 GND - "P15", # 117 IO_L74N_DOUT_BUSY_1 - "P14", # 118 IO_L74P_AWAKE_1 - "N15", # 119 IO_L47N_LDC_M1DQ1_1 - "N14", # 120 IO_L47P_FWE_B_M1DQ0_1 - "M15", # 121 IO_L46N_FOE_B_M1DQ3_1 - "M13", # 122 IO_L46P_FCS_B_M1DQS2_1 - "L12", # 123 IO_L40N_GCLK10_M1A6_1 - "K12", # 124 IO_L40P_GCLK11_M1A5_1 - "K11", # 125 IO_L38N_A4_M1CLKN_1 - "K10", # 126 IO_L38P_A5_M1CLK_1 - "J13", # 127 IO_L36N_A8_M1BA1_1 - "J11", # 128 IO_L36P_A9_M1BA0_1 - "None", # 129 GND - "G13", # 130 IO_L34N_A12_M1BA2_1_NOTLX4 - "H12", # 131 IO_L34P_A13_M1WE_1_NOTLX4 - "H11", # 132 IO_L32N_A16_M1A9_1_NOTLX4 - "H10", # 133 IO_L32P_A17_M1A8_1_NOTLX4 - "F12", # 134 IO_L31N_A18_M1A12_1_NOTLX4 - "F11", # 135 IO_L31P_A19_M1CKE_1_NOTLX4 - "G12", # 136 IO_L30N_A20_M1A11_1_NOTLX4 - "G11", # 137 IO_L30P_A21_M1RESET_1_NOTLX4 - "None", # 138 GND - "None", # 139 FPGA_BANK3_POWER - "None") # 140 FPGA_BANK3_POWER -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk3" - default_clk_period = 10.526 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-2csg225", _ios, _connectors) diff --git a/migen/build/platforms/de0nano.py b/migen/build/platforms/de0nano.py deleted file mode 100644 index 4ef34daf..00000000 --- a/migen/build/platforms/de0nano.py +++ /dev/null @@ -1,103 +0,0 @@ -# This file is Copyright (c) 2013 Florent Kermarrec -# License: BSD - -from migen.build.generic_platform import * -from migen.build.altera import AlteraPlatform -from migen.build.altera.programmer import USBBlaster - - -_io = [ - ("clk50", 0, Pins("R8"), IOStandard("3.3-V LVTTL")), - - ("user_led", 0, Pins("A15"), IOStandard("3.3-V LVTTL")), - ("user_led", 1, Pins("A13"), IOStandard("3.3-V LVTTL")), - ("user_led", 2, Pins("B13"), IOStandard("3.3-V LVTTL")), - ("user_led", 3, Pins("A11"), IOStandard("3.3-V LVTTL")), - ("user_led", 4, Pins("D1"), IOStandard("3.3-V LVTTL")), - ("user_led", 5, Pins("F3"), IOStandard("3.3-V LVTTL")), - ("user_led", 6, Pins("B1"), IOStandard("3.3-V LVTTL")), - ("user_led", 7, Pins("L3"), IOStandard("3.3-V LVTTL")), - - ("key", 0, Pins("J15"), IOStandard("3.3-V LVTTL")), - ("key", 1, Pins("E1"), IOStandard("3.3-V LVTTL")), - - ("sw", 0, Pins("M1"), IOStandard("3.3-V LVTTL")), - ("sw", 1, Pins("T9"), IOStandard("3.3-V LVTTL")), - ("sw", 2, Pins("B9"), IOStandard("3.3-V LVTTL")), - ("sw", 3, Pins("M15"), IOStandard("3.3-V LVTTL")), - - ("serial", 0, - Subsignal("tx", Pins("D3"), IOStandard("3.3-V LVTTL")), - Subsignal("rx", Pins("C3"), IOStandard("3.3-V LVTTL")) - ), - - ("sdram_clock", 0, Pins("R4"), IOStandard("3.3-V LVTTL")), - ("sdram", 0, - Subsignal("a", Pins("P2 N5 N6 M8 P8 T7 N8 T6 R1 P1 N2 N1 L4")), - Subsignal("ba", Pins("M7 M6")), - Subsignal("cs_n", Pins("P6")), - Subsignal("cke", Pins("L7")), - Subsignal("ras_n", Pins("L2")), - Subsignal("cas_n", Pins("L1")), - Subsignal("we_n", Pins("C2")), - Subsignal("dq", Pins("G2 G1 L8 K5 K2 J2 J1 R7 T4 T2 T3 R3 R5 P3 N3 K1")), - Subsignal("dm", Pins("R6 T5")), - IOStandard("3.3-V LVTTL") - ), - - ("epcs", 0, - Subsignal("data0", Pins("H2")), - Subsignal("dclk", Pins("H1")), - Subsignal("ncs0", Pins("D2")), - Subsignal("asd0", Pins("C1")), - IOStandard("3.3-V LVTTL") - ), - - ("i2c", 0, - Subsignal("sclk", Pins("F2")), - Subsignal("sdat", Pins("F1")), - IOStandard("3.3-V LVTTL") - ), - - ("g_sensor", 0, - Subsignal("cs_n", Pins("G5")), - Subsignal("int", Pins("M2")), - IOStandard("3.3-V LVTTL") - ), - - ("adc", 0, - Subsignal("cs_n", Pins("A10")), - Subsignal("saddr", Pins("B10")), - Subsignal("sclk", Pins("B14")), - Subsignal("sdat", Pins("A9")), - IOStandard("3.3-V LVTTL") - ), - - ("gpio_0", 0, - Pins("D3 C3 A2 A3 B3 B4 A4 B5 A5 D5 B6 A6 B7 D6 A7 C6", - "C8 E6 E7 D8 E8 F8 F9 E9 C9 D9 E11 E10 C11 B11 A12 D11", - "D12 B12"), - IOStandard("3.3-V LVTTL") - ), - ("gpio_1", 0, - Pins("F13 T15 T14 T13 R13 T12 R12 T11 T10 R11 P11 R10 N12 P9 N9 N11", - "L16 K16 R16 L15 P15 P16 R14 N16 N15 P14 L14 N14 M10 L13 J16 K15", - "J13 J14"), - IOStandard("3.3-V LVTTL") - ), - ("gpio_2", 0, - Pins("A14 B16 C14 C16 C15 D16 D15 D14 F15 F16 F14 G16 G15"), - IOStandard("3.3-V LVTTL") - ), -] - - -class Platform(AlteraPlatform): - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - AlteraPlatform.__init__(self, "EP4CE22F17C6", _io) - - def create_programmer(self): - return USBBlaster() diff --git a/migen/build/platforms/lx9_microboard.py b/migen/build/platforms/lx9_microboard.py deleted file mode 100644 index fb13b1cb..00000000 --- a/migen/build/platforms/lx9_microboard.py +++ /dev/null @@ -1,131 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("user_btn", 0, Pins("V4"), IOStandard("LVCMOS33"), - Misc("PULLDOWN"), Misc("TIG")), - - ("user_led", 0, Pins("P4"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - ("user_led", 1, Pins("L6"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - ("user_led", 2, Pins("F5"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - ("user_led", 3, Pins("C2"), Misc("SLEW=QUIETIO"), IOStandard("LVCMOS18")), - - ("user_dip", 0, Pins("B3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - ("user_dip", 1, Pins("A3"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - ("user_dip", 2, Pins("B4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - ("user_dip", 3, Pins("A4"), Misc("PULLDOWN"), IOStandard("LVCMOS33")), - - # TI CDCE913 programmable triple-output PLL - ("clk_y1", 0, Pins("V10"), IOStandard("LVCMOS33")), # default: 40 MHz - ("clk_y2", 0, Pins("K15"), IOStandard("LVCMOS33")), # default: 66 2/3 MHz - ("clk_y3", 0, Pins("C10"), IOStandard("LVCMOS33")), # default: 100 MHz - - # Maxim DS1088LU oscillator, not populated - ("clk_backup", 0, Pins("R8"), IOStandard("LVCMOS33")), - - # TI CDCE913 PLL I2C control - ("pll", 0, - Subsignal("scl", Pins("P12")), - Subsignal("sda", Pins("U13")), - Misc("PULLUP"), - IOStandard("LVCMOS33")), - - # Micron N25Q128 SPI Flash - ("spiflash", 0, - Subsignal("clk", Pins("R15")), - Subsignal("cs_n", Pins("V3")), - Subsignal("dq", Pins("T13 R13 T14 V14")), - IOStandard("LVCMOS33")), - - # PMOD extension connectors - ("pmod", 0, - Subsignal("d", Pins("F15 F16 C17 C18 F14 G14 D17 D18")), - IOStandard("LVCMOS33")), - ("pmod", 1, - Subsignal("d", Pins("H12 G13 E16 E18 K12 K13 F17 F18")), - IOStandard("LVCMOS33")), - - ("pmod_diff", 0, - Subsignal("io", Pins("F15 C17 F14 D17 H12 E16 K12 F17")), - Subsignal("iob", Pins("F16 C18 G14 D18 G13 E18 K13 F18")), - IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("T7"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("R7"), Misc("PULLUP")), - IOStandard("LVCMOS33")), - - ("ddram_clock", 0, - Subsignal("p", Pins("G3")), - Subsignal("n", Pins("G1")), - IOStandard("MOBILE_DDR")), # actually DIFF_ - - # Micron MT46H32M16LFBF-5 LPDDR - ("ddram", 0, - Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 " - "D2 D1 F4 D3 G6")), - Subsignal("ba", Pins("F2 F1")), - Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 " - "M3 M1 N2 N1 T2 T1 U2 U1")), - Subsignal("cke", Pins("H7")), - Subsignal("we_n", Pins("E3")), - Subsignal("cs_n", Pins("K6")), # NC! - Subsignal("cas_n", Pins("K5")), - Subsignal("ras_n", Pins("L5")), - Subsignal("dm", Pins("K3", "K4")), - Subsignal("dqs", Pins("L4", "P2")), - Subsignal("rzq", Pins("N4")), - IOStandard("MOBILE_DDR")), - - # Nat Semi DP83848J 10/100 Ethernet PHY - # pull-ups on col and rx_data set phy addr to 11111b - # and prevent isolate mode (addr 00000b) - ("eth_clocks", 0, - Subsignal("rx", Pins("L15")), - Subsignal("tx", Pins("H17")), - IOStandard("LVCMOS33")), - - ("eth", 0, - Subsignal("col", Pins("M18"), Misc("PULLUP")), - Subsignal("crs", Pins("N17"), Misc("PULLDOWN")), - Subsignal("mdc", Pins("M16"), Misc("PULLDOWN")), - Subsignal("mdio", Pins("L18"), Misc("PULLUP")), # 1k5 ext PULLUP - Subsignal("rst_n", Pins("T18"), Misc("TIG")), - Subsignal("rx_data", Pins("T17 N16 N15 P18"), Misc("PULLUP")), - Subsignal("dv", Pins("P17"), Misc("PULLDOWN")), # MII - Subsignal("rx_er", Pins("N18"), Misc("PULLUP")), # auto MDIX - Subsignal("tx_data", Pins("K18 K17 J18 J16")), - Subsignal("tx_en", Pins("L17")), - Subsignal("tx_er", Pins("L16")), # NC! - IOStandard("LVCMOS33")), - ] - - -class Platform(XilinxPlatform): - default_clk_name = "clk_y3" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-2csg324", _io) - self.add_platform_command(""" -CONFIG VCCAUX = "3.3"; -""") - self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g SPI_buswidth:4" - self.toolchain.ise_commands = """ -promgen -w -spi -c FF -p mcs -o {build_name}.mcs -u 0 {build_name}.bit -""" - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - eth_clocks = self.lookup_request("eth_clocks") - self.add_period_constraint(eth_clocks.rx, 40) - self.add_period_constraint(eth_clocks.tx, 40) - self.add_platform_command(""" -TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns; -TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns; -""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) - except ConstraintError: - pass diff --git a/migen/build/platforms/m1.py b/migen/build/platforms/m1.py deleted file mode 100644 index 65216c88..00000000 --- a/migen/build/platforms/m1.py +++ /dev/null @@ -1,152 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import UrJTAG - - -_io = [ - ("user_led", 0, Pins("B16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - ("user_led", 1, Pins("A16"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - - ("user_btn", 0, Pins("AB4"), IOStandard("LVCMOS33")), - ("user_btn", 1, Pins("AA4"), IOStandard("LVCMOS33")), - ("user_btn", 2, Pins("AB5"), IOStandard("LVCMOS33")), - - ("clk50", 0, Pins("AB11"), IOStandard("LVCMOS33")), - - # When executing softcore code in-place from the flash, we want - # the flash reset to be released before the system reset. - ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)), - ("norflash", 0, - Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22", - "F21 K17 J17 E22 E20 H18 H19 F20", - "G19 C22 C20 D22 D21 F19 F18 D20 D19")), - Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7", - "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")), - Subsignal("oe_n", Pins("M22")), - Subsignal("we_n", Pins("N20")), - Subsignal("ce_n", Pins("M21")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8) - ), - - ("serial", 0, - Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")) - ), - - ("ddram_clock", 0, - Subsignal("p", Pins("M3")), - Subsignal("n", Pins("L4")), - IOStandard("SSTL2_I") - ), - ("ddram", 0, - Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")), - Subsignal("ba", Pins("A2 E6")), - Subsignal("cs_n", Pins("F7")), - Subsignal("cke", Pins("G7")), - Subsignal("ras_n", Pins("E5")), - Subsignal("cas_n", Pins("C4")), - Subsignal("we_n", Pins("D3")), - Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3", - "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4", - "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")), - Subsignal("dm", Pins("E1 E3 F3 G4")), - Subsignal("dqs", Pins("F1 F2 H5 H6")), - IOStandard("SSTL2_I") - ), - - ("eth_clocks", 0, - Subsignal("phy", Pins("M20")), - Subsignal("rx", Pins("H22")), - Subsignal("tx", Pins("H21")), - IOStandard("LVCMOS33") - ), - ("eth", 0, - Subsignal("rst_n", Pins("R22")), - Subsignal("dv", Pins("V21")), - Subsignal("rx_er", Pins("V22")), - Subsignal("rx_data", Pins("U22 U20 T22 T21")), - Subsignal("tx_en", Pins("N19")), - Subsignal("tx_er", Pins("M19")), - Subsignal("tx_data", Pins("M16 L15 P19 P20")), - Subsignal("col", Pins("W20")), - Subsignal("crs", Pins("W22")), - IOStandard("LVCMOS33") - ), - - ("vga_out", 0, - Subsignal("clk", Pins("A11")), - Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")), - Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")), - Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")), - Subsignal("hsync_n", Pins("A14")), - Subsignal("vsync_n", Pins("C15")), - Subsignal("psave_n", Pins("B14")), - IOStandard("LVCMOS33") - ), - - ("mmc", 0, - Subsignal("clk", Pins("A10")), - Subsignal("cmd", Pins("B18")), - Subsignal("dat", Pins("A18 E16 C17 A17")), - IOStandard("LVCMOS33") - ), - - # Digital video mixer extension board - ("dvi_in", 0, - Subsignal("clk", Pins("A20")), - Subsignal("data0_n", Pins("A21")), - Subsignal("data1", Pins("B21")), - Subsignal("data2_n", Pins("B22")), - Subsignal("scl", Pins("G16")), - Subsignal("sda", Pins("G17")), - IOStandard("LVCMOS33") - ), - ("dvi_in", 1, - Subsignal("clk", Pins("H17")), - Subsignal("data0_n", Pins("H16")), - Subsignal("data1", Pins("F17")), - Subsignal("data2_n", Pins("F16")), - Subsignal("scl", Pins("J16")), - Subsignal("sda", Pins("K16")), - IOStandard("LVCMOS33") - ), - ("dvi_pots", 0, - Subsignal("charge", Pins("A18")), # SD_DAT0 - Subsignal("blackout", Pins("C17")), # SD_DAT2 - Subsignal("crossfade", Pins("A17")), # SD_DAT3 - IOStandard("LVCMOS33") - ) -] - - -class Platform(XilinxPlatform): - identifier = 0x4D31 - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io) - - def create_programmer(self): - return UrJTAG(cable="milkymist", flash_proxy_basename="fjmem-m1.bit") - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - eth_clocks = self.lookup_request("eth_clocks") - self.add_period_constraint(eth_clocks.rx, 40) - self.add_period_constraint(eth_clocks.tx, 40) - self.add_platform_command(""" -TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns; -TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns; -""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) - except ConstraintError: - pass - - for i in range(2): - si = "dviclk"+str(i) - try: - self.add_period_constraint(self.lookup_request("dvi_in", i).clk, 26.7) - except ConstraintError: - pass diff --git a/migen/build/platforms/mercury.py b/migen/build/platforms/mercury.py deleted file mode 100644 index 699218df..00000000 --- a/migen/build/platforms/mercury.py +++ /dev/null @@ -1,138 +0,0 @@ -# This file is Copyright (c) 2015 William D. Jones -# License: BSD - -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg - - -_io = [ - ("clk50", 0, Pins("P43"), IOStandard("LVCMOS33")), - - ("user_btn", 0, Pins("P41"), IOStandard("LVTTL")), - - # The serial interface and flash memory have a shared SPI bus. - # FPGA is secondary - ("spiserial", 0, - Subsignal("cs_n", Pins("P39"), IOStandard("LVTTL")), - Subsignal("clk", Pins("P53"), IOStandard("LVTTL")), - Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")), - Subsignal("miso", Pins("P51"), IOStandard("LVTTL")) - ), - - # FPGA is primary - ("spiflash", 0, - Subsignal("cs_n", Pins("P27"), IOStandard("LVTTL")), - Subsignal("clk", Pins("P53"), IOStandard("LVTTL")), - Subsignal("mosi", Pins("P46"), IOStandard("LVTTL")), - Subsignal("miso", Pins("P51"), IOStandard("LVTTL")) - ), - - ("spiflash2x", 0, - Subsignal("cs_n", Pins("P27")), - Subsignal("clk", Pins("P53")), - Subsignal("dq", Pins("P46", "P51")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - # ADC over SPI- FPGA is primary - ("adc", 0, - Subsignal("cs_n", Pins("P12"), IOStandard("LVTTL")), - Subsignal("clk", Pins("P9"), IOStandard("LVTTL")), - Subsignal("mosi", Pins("P10"), IOStandard("LVTTL")), - Subsignal("miso", Pins("P21"), IOStandard("LVTTL")) - ), - - # GPIO control- SRAM and connectors are shared: these pins control how - # to access each. Recommended to combine with gpio_sram_bus extension, - # since these pins are related but not exposed on connectors. - ("gpio_ctl", 0, - Subsignal("ce_n", Pins("P3")), # Memory chip-enable. Called MEM_CEN - # in schematic. - Subsignal("bussw_oe_n", Pins("P30")), # 5V tolerant GPIO is shared - # w/ memory using this pin. - IOStandard("LVTTL"), Misc("SLEW=FAST") - ) -] - -# Perhaps define some connectors as having a specific purpose- i.e. a 5V GPIO -# bus with data, peripheral-select, and control signals? -_connectors = [ - ("GPIO", """P59 P60 P61 P62 P64 P57 - P56 P52 P50 P49 P85 P84 - P83 P78 P77 P65 P70 P71 - P72 P73 P5 P4 P6 P98 - P94 P93 P90 P89 P88 P86"""), # 5V I/O- LVTTL - ("DIO", "P20 P32 P33 P34 P35 P36 P37"), # Fast 3.3V IO (Directly attached - # to FPGA)- LVCMOS33 - ("CLKIO", "P40 P44"), # Clock IO (Can be used as GPIO)- LVCMOS33 - ("INPUT", "P68 P97 P7 P82"), # Input-only pins- LVCMOS33 - ("LED", "P13 P15 P16 P19") # LEDs can be used as pins as well- LVTTL. -] - -# Some default useful extensions- use platform.add_extension() to use, e.g. -# from migen.build.platforms import mercury -# plat = mercury.Platform() -# plat.add_extension(mercury.gpio_sram) - -# SRAM and 5V-tolerant I/O share a parallel bus on 200k gate version. The SRAM -# controller needs to take care of switching the bus between the two. Meant to -# be Cat() into one GPIO bus, and combined with gpio_ctl. -gpio_sram = [ - ("gpio_sram_bus", 0, - Subsignal("a", Pins("""GPIO:0 GPIO:1 GPIO:2 GPIO:3 - GPIO:4 GPIO:5 GPIO:6 GPIO:7 - GPIO:8 GPIO:9 GPIO:10 GPIO:11 - GPIO:12 GPIO:13 GPIO:14 GPIO:15 - GPIO:16 GPIO:17 GPIO:18 GPIO:19""")), - # A19 is actually unused- free for GPIO - # 8-bit data bus - Subsignal("d", Pins("""GPIO:20 GPIO:21 GPIO:22 GPIO:23 - GPIO:24 GPIO:25 GPIO:26 GPIO:27""")), - Subsignal("we_n", Pins("GPIO:28")), - Subsignal("unused", Pins("GPIO:29")), # Only used by GPIO. - # Subsignal("oe_n", Pins()), # If OE wasn't tied to ground on Mercury, - # this pin would be here. - IOStandard("LVTTL"), Misc("SLEW=FAST") - ) -] - -# The "serial port" is in fact over SPI. The creators of the board provide a -# VHDL file for talking over this interface. In light of space constraints and -# the fact that both the FT245RL and FPGA can BOTH be SPI primaries, however, -# it may be necessary to sacrifice two "high-speed" (DIO, INPUT) pins instead. -serial = [ - ("serial", 0, - Subsignal("tx", Pins("DIO:0"), IOStandard("LVCMOS33")), # FTDI D1 - Subsignal("rx", Pins("INPUT:0"), IOStandard("LVCMOS33")) - ) # FTDI D0 -] - -leds = [ - ("user_led", 0, Pins("LED:0"), IOStandard("LVTTL")), - ("user_led", 1, Pins("LED:1"), IOStandard("LVTTL")), - ("user_led", 2, Pins("LED:2"), IOStandard("LVTTL")), - ("user_led", 3, Pins("LED:3"), IOStandard("LVTTL")) -] - -# See: http://www.micro-nova.com/mercury-baseboard/ -# Not implemented yet. -baseboard = [ -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self, device="xc3s200a-4-vq100"): - XilinxPlatform.__init__(self, device, _io, _connectors) - # Small device- optimize for AREA instead of SPEED (LM32 runs at about - # 60-65MHz in AREA configuration). - self.toolchain.xst_opt = """-ifmt MIXED --use_new_parser yes --opt_mode AREA --register_balancing yes""" - - def create_programmer(self): - raise NotImplementedError diff --git a/migen/build/platforms/mimasv2.py b/migen/build/platforms/mimasv2.py deleted file mode 100644 index 703fdc49..00000000 --- a/migen/build/platforms/mimasv2.py +++ /dev/null @@ -1,124 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("clk100", 0, Pins("V10"), IOStandard("LVCMOS33")), - ("clk12", 0, Pins("D9"), IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("A8"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("rx", Pins("B8"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))), - - ("spiflash", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("mosi", Pins("T13")), - Subsignal("miso", Pins("R13"), Misc("PULLUP")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST")), - - ("ddram_clock", 0, - Subsignal("p", Pins("G3")), - Subsignal("n", Pins("G1")), - IOStandard("MOBILE_DDR")), - - ("ddram", 0, - Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")), - Subsignal("ba", Pins("F2 F1")), - Subsignal("cke", Pins("H7")), - Subsignal("ras_n", Pins("L5")), - Subsignal("cas_n", Pins("K5")), - Subsignal("we_n", Pins("E3")), - Subsignal( - "dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1") - ), - Subsignal("dqs", Pins("L4 P2")), - Subsignal("dm", Pins("K3 K4")), - IOStandard("MOBILE_DDR")), - - ("dipswitch", 0, Pins("C17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 1, Pins("C18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 2, Pins("D17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 3, Pins("D18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 4, Pins("E18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 5, Pins("E16"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 6, Pins("F18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("dipswitch", 7, Pins("F17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - - ("buttonswitch", 0, Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 1, Pins("K17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 2, Pins("L17"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 3, Pins("M16"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 4, Pins("L18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - ("buttonswitch", 5, Pins("M18"), IOStandard("LVCMOS33"), Misc("PULLUP")), - - ("user_led", 0, Pins("T18"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 1, Pins("T17"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 2, Pins("U18"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 3, Pins("U17"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 4, Pins("N16"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 5, Pins("N15"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 6, Pins("P16"), IOStandard("LVCMOS33"), Drive(8)), - ("user_led", 7, Pins("P15"), IOStandard("LVCMOS33"), Drive(8)), - - ("mmc", 0, - Subsignal("dat", Pins("K14 G18 J13 L13"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - - Subsignal("cmd", Pins("G16"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - - Subsignal("clk", Pins("L12"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))), - - ("sevenseg", 0, - Subsignal("segment7", Pins("A3"), IOStandard("LVCMOS33")), # A - Subsignal("segment6", Pins("B4"), IOStandard("LVCMOS33")), # B - Subsignal("segment5", Pins("A4"), IOStandard("LVCMOS33")), # C - Subsignal("segment4", Pins("C4"), IOStandard("LVCMOS33")), # D - Subsignal("segment3", Pins("C5"), IOStandard("LVCMOS33")), # E - Subsignal("segment2", Pins("D6"), IOStandard("LVCMOS33")), # F - Subsignal("segment1", Pins("C6"), IOStandard("LVCMOS33")), # G - Subsignal("segment0", Pins("A5"), IOStandard("LVCMOS33")), # Dot - Subsignal("enable0", Pins("B2"), IOStandard("LVCMOS33")), # EN0 - Subsignal("enable1", Pins("A2"), IOStandard("LVCMOS33")), # EN1 - Subsignal("enable2", Pins("B3"), IOStandard("LVCMOS33"))), # EN2 - - - ("audio", 0, - Subsignal("channel1", Pins("B16"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("channel2", Pins("A16"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))), - - ("vga_out", 0, - Subsignal("hsync_n", Pins("B12"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("vsync_n", Pins("A12"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("r", Pins("A9 B9 C9"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("g", Pins("C10 A10 C11"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST")), - Subsignal("b", Pins("B11 A11"), IOStandard("LVCMOS33"), - Misc("SLEW=FAST"))) -] - -_connectors = [ - ("P6", "T3 R3 V5 U5 V4 T4 V7 U7"), - ("P7", "V11 U11 V13 U13 T10 R10 T11 R11"), - ("P8", "L16 L15 K16 K15 J18 J16 H18 H17") -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-csg324-2", _io, _connectors) - - def create_programmer(self): - raise NotImplementedError diff --git a/migen/build/platforms/mixxeo.py b/migen/build/platforms/mixxeo.py deleted file mode 100644 index 8d4c85d8..00000000 --- a/migen/build/platforms/mixxeo.py +++ /dev/null @@ -1,188 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import UrJTAG - - -_io = [ - ("user_led", 0, Pins("V5"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - - ("clk50", 0, Pins("AB13"), IOStandard("LVCMOS33")), - - # When executing softcore code in-place from the flash, we want - # the flash reset to be released before the system reset. - ("norflash_rst_n", 0, Pins("P22"), IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8)), - ("norflash", 0, - Subsignal("adr", Pins("L22 L20 K22 K21 J19 H20 F22", - "F21 K17 J17 E22 E20 H18 H19 F20", - "G19 C22 C20 D22 D21 F19 F18 D20 D19")), - Subsignal("d", Pins("AA20 U14 U13 AA6 AB6 W4 Y4 Y7", - "AA2 AB2 V15 AA18 AB18 Y13 AA12 AB12"), Misc("PULLDOWN")), - Subsignal("oe_n", Pins("M22")), - Subsignal("we_n", Pins("N20")), - Subsignal("ce_n", Pins("M21")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST"), Drive(8) - ), - - ("serial", 0, - Subsignal("tx", Pins("L17"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("K18"), IOStandard("LVCMOS33"), Misc("PULLUP")) - ), - - ("ddram_clock", 0, - Subsignal("p", Pins("M3")), - Subsignal("n", Pins("L4")), - IOStandard("SSTL2_I") - ), - ("ddram", 0, - Subsignal("a", Pins("B1 B2 H8 J7 E4 D5 K7 F5 G6 C1 C3 D1 D2")), - Subsignal("ba", Pins("A2 E6")), - Subsignal("cs_n", Pins("F7")), - Subsignal("cke", Pins("G7")), - Subsignal("ras_n", Pins("E5")), - Subsignal("cas_n", Pins("C4")), - Subsignal("we_n", Pins("D3")), - Subsignal("dq", Pins("Y2 W3 W1 P8 P7 P6 P5 T4 T3", - "U4 V3 N6 N7 M7 M8 R4 P4 M6 L6 P3 N4", - "M5 V2 V1 U3 U1 T2 T1 R3 R1 P2 P1")), - Subsignal("dm", Pins("E1 E3 F3 G4")), - Subsignal("dqs", Pins("F1 F2 H5 H6")), - IOStandard("SSTL2_I") - ), - - ("eth_clocks", 0, - Subsignal("phy", Pins("M20")), - Subsignal("rx", Pins("H22")), - Subsignal("tx", Pins("H21")), - IOStandard("LVCMOS33") - ), - ("eth", 0, - Subsignal("rst_n", Pins("R22")), - Subsignal("dv", Pins("V21")), - Subsignal("rx_er", Pins("V22")), - Subsignal("rx_data", Pins("U22 U20 T22 T21")), - Subsignal("tx_en", Pins("N19")), - Subsignal("tx_er", Pins("M19")), - Subsignal("tx_data", Pins("M16 L15 P19 P20")), - Subsignal("col", Pins("W20")), - Subsignal("crs", Pins("W22")), - IOStandard("LVCMOS33") - ), - - ("vga_out", 0, - Subsignal("clk", Pins("A10")), - Subsignal("r", Pins("C6 B6 A6 C7 A7 B8 A8 D9")), - Subsignal("g", Pins("C8 C9 A9 D7 D8 D10 C10 B10")), - Subsignal("b", Pins("D11 C12 B12 A12 C13 A13 D14 C14")), - Subsignal("hsync_n", Pins("A14")), - Subsignal("vsync_n", Pins("C15")), - Subsignal("psave_n", Pins("B14")), - IOStandard("LVCMOS33") - ), - ("dvi_out", 0, - Subsignal("clk_p", Pins("W12"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("Y12"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("Y16"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("W15"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("AA16"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("AB16"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("Y15"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("AB15"), IOStandard("TMDS_33")), - ), - - ("mmc", 0, - Subsignal("clk", Pins("J3")), - Subsignal("cmd", Pins("K1")), - Subsignal("dat", Pins("J6 K6 N1 K5")), - IOStandard("LVCMOS33") - ), - - ("dvi_in", 0, - Subsignal("clk_p", Pins("K20"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("K19"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("B21"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("B22"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("A20"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("A21"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("K16"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("J16"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("G20"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("H16"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("G22"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("G17"), IOStandard("LVCMOS33")) - ), - ("dvi_in", 1, - Subsignal("clk_p", Pins("C11"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("A11"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("B18"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("A18"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("C17"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("A17"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("E16"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("D17"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("F17"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("F16"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("G16"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("B20"), IOStandard("LVCMOS33")) - ), - ("dvi_in", 2, - Subsignal("clk_p", Pins("Y11"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("AB11"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("V11"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("W11"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("AA10"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("AB10"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("R11"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("T11"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("C16"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("B16"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("D6"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("A4"), IOStandard("LVCMOS33")) - ), - ("dvi_in", 3, - Subsignal("clk_p", Pins("J20"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("J22"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("P18"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("R19"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("P17"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("N16"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("M17"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("M18"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("P21"), IOStandard("LVCMOS33")), - Subsignal("sda", Pins("N22"), IOStandard("LVCMOS33")), - Subsignal("hpd_notif", Pins("H17"), IOStandard("LVCMOS33")), - Subsignal("hpd_en", Pins("C19"), IOStandard("LVCMOS33")) - ), -] - - -class Platform(XilinxPlatform): - identifier = 0x4D58 - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx45-fgg484-2", _io) - self.add_platform_command("CONFIG VCCAUX=\"3.3\";\n") - - def create_programmer(self): - return UrJTAG("fjmem-mixxeo.bit") - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - eth_clocks = self.lookup_request("eth_clocks") - self.add_period_constraint(eth_clocks.rx, 40) - self.add_period_constraint(eth_clocks.tx, 40) - self.add_platform_command(""" -TIMESPEC "TS{phy_tx_clk}_io" = FROM "GRP{phy_tx_clk}" TO "PADS" 10 ns; -TIMESPEC "TS{phy_rx_clk}_io" = FROM "PADS" TO "GRP{phy_rx_clk}" 10 ns; -""", phy_rx_clk=eth_clocks.rx, phy_tx_clk=eth_clocks.tx) - except ConstraintError: - pass - - for i in range(4): - try: - self.add_period_constraint(self.lookup_request("dvi_in", i).clk_p, 12) - except ConstraintError: - pass diff --git a/migen/build/platforms/ml605.py b/migen/build/platforms/ml605.py deleted file mode 100644 index 04184b74..00000000 --- a/migen/build/platforms/ml605.py +++ /dev/null @@ -1,60 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - # System clock (Differential 200MHz) - ("clk200", 0, - Subsignal("p", Pins("J9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("n", Pins("H9"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")) - ), - - # User clock (66MHz) - ("clk66", 0, Pins("U23"), IOStandard("LVCMOS25")), - - # CPU reset switch - ("cpu_reset", 0, Pins("H10"), IOStandard("SSTL15")), - - # LEDs - ("user_led", 0, Pins("AC22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 1, Pins("AC24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 2, Pins("AE22"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 3, Pins("AE23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 4, Pins("AB23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 5, Pins("AG23"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 6, Pins("AE24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - ("user_led", 7, Pins("AD24"), IOStandard("LVCMOS25"), Misc("SLEW=SLOW")), - - # USB-to-UART - ("serial", 0, - Subsignal("tx", Pins("J25"), IOStandard("LVCMOS25")), - Subsignal("rx", Pins("J24"), IOStandard("LVCMOS25")) - ), - - # 10/100/1000 Tri-Speed Ethernet PHY - ("eth_clocks", 0, - Subsignal("rx", Pins("AP11")), - Subsignal("tx", Pins("AD12")), - IOStandard("LVCMOS25") - ), - ("eth", 0, - Subsignal("rst_n", Pins("AH13")), - Subsignal("dv", Pins("AM13")), - Subsignal("rx_er", Pins("AG12")), - Subsignal("rx_data", Pins("AN13 AF14 AE14 AN12 AM12 AD11 AC12 AC13")), - Subsignal("tx_en", Pins("AJ10")), - Subsignal("tx_er", Pins("AH10")), - Subsignal("tx_data", Pins("AM11 AL11 AG10 AG11 AL10 AM10 AE11 AF11")), - Subsignal("col", Pins("AK13")), - Subsignal("crs", Pins("AL13")), - IOStandard("LVCMOS25") - ) -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk200" - default_clk_period = 5 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6vlx240t-ff1156-1", _io) diff --git a/migen/build/platforms/papilio_pro.py b/migen/build/platforms/papilio_pro.py deleted file mode 100644 index 8ee33005..00000000 --- a/migen/build/platforms/papilio_pro.py +++ /dev/null @@ -1,62 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg - - -_io = [ - ("user_led", 0, Pins("P112"), IOStandard("LVCMOS33"), Drive(24), Misc("SLEW=QUIETIO")), - - ("clk32", 0, Pins("P94"), IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("P105"), IOStandard("LVCMOS33"), Misc("SLEW=SLOW")), - Subsignal("rx", Pins("P101"), IOStandard("LVCMOS33"), Misc("PULLUP")) - ), - - ("spiflash", 0, - Subsignal("cs_n", Pins("P38")), - Subsignal("clk", Pins("P70")), - Subsignal("mosi", Pins("P64")), - Subsignal("miso", Pins("P65"), Misc("PULLUP")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), - ("spiflash2x", 0, - Subsignal("cs_n", Pins("P38")), - Subsignal("clk", Pins("P70")), - Subsignal("dq", Pins("P64", "P65")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ), - - ("sdram_clock", 0, Pins("P32"), IOStandard("LVCMOS33"), Misc("SLEW=FAST")), - ("sdram", 0, - Subsignal("a", Pins("P140 P139 P138 P137 P46 P45 P44", - "P43 P41 P40 P141 P35 P34")), - Subsignal("ba", Pins("P143 P142")), - Subsignal("cs_n", Pins("P1")), - Subsignal("cke", Pins("P33")), - Subsignal("ras_n", Pins("P2")), - Subsignal("cas_n", Pins("P5")), - Subsignal("we_n", Pins("P6")), - Subsignal("dq", Pins("P9 P10 P11 P12 P14 P15 P16 P8 P21 P22 P23 P24 P26 P27 P29 P30")), - Subsignal("dm", Pins("P7 P17")), - IOStandard("LVCMOS33"), Misc("SLEW=FAST") - ) -] - -_connectors = [ - ("A", "P48 P51 P56 P58 P61 P66 P67 P75 P79 P81 P83 P85 P88 P93 P98 P100"), - ("B", "P99 P97 P92 P87 P84 P82 P80 P78 P74 P95 P62 P59 P57 P55 P50 P47"), - ("C", "P114 P115 P116 P117 P118 P119 P120 P121 P123 P124 P126 P127 P131 P132 P133 P134") -] - - -class Platform(XilinxPlatform): - identifier = 0x5050 - default_clk_name = "clk32" - default_clk_period = 31.25 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx9-tqg144-2", _io, _connectors) - - def create_programmer(self): - return XC3SProg("papilio", "bscan_spi_lx9_papilio.bit") diff --git a/migen/build/platforms/pipistrello.py b/migen/build/platforms/pipistrello.py deleted file mode 100644 index c202556a..00000000 --- a/migen/build/platforms/pipistrello.py +++ /dev/null @@ -1,138 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform -from migen.build.xilinx.programmer import XC3SProg - - -_io = [ - ("user_led", 0, Pins("V16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at hdmi - ("user_led", 1, Pins("U16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at hdmi - ("user_led", 2, Pins("A16"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # green at msd - ("user_led", 3, Pins("A15"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at msd - ("user_led", 4, Pins("A12"), IOStandard("LVTTL"), Drive(8), Misc("SLEW=QUIETIO")), # red at usb - - ("user_btn", 0, Pins("N14"), IOStandard("LVTTL"), Misc("PULLDOWN")), - - ("clk50", 0, Pins("H17"), IOStandard("LVTTL")), - - ("serial", 0, - Subsignal("tx", Pins("A10")), - Subsignal("rx", Pins("A11"), Misc("PULLUP")), - Subsignal("cts", Pins("C10"), Misc("PULLUP")), - Subsignal("rts", Pins("A9"), Misc("PULLUP")), - IOStandard("LVTTL"), - ), - - ("usb_fifo", 0, - Subsignal("data", Pins("A11 A10 C10 A9 B9 A8 B8 A7")), - Subsignal("rxf_n", Pins("C7")), - Subsignal("txe_n", Pins("A6")), - Subsignal("rd_n", Pins("B6")), - Subsignal("wr_n", Pins("A5")), - Subsignal("siwua", Pins("C5")), - IOStandard("LVTTL"), - ), - - ("hdmi", 0, - Subsignal("clk_p", Pins("U5"), IOStandard("TMDS_33")), - Subsignal("clk_n", Pins("V5"), IOStandard("TMDS_33")), - Subsignal("data0_p", Pins("T6"), IOStandard("TMDS_33")), - Subsignal("data0_n", Pins("V6"), IOStandard("TMDS_33")), - Subsignal("data1_p", Pins("U7"), IOStandard("TMDS_33")), - Subsignal("data1_n", Pins("V7"), IOStandard("TMDS_33")), - Subsignal("data2_p", Pins("U8"), IOStandard("TMDS_33")), - Subsignal("data2_n", Pins("V8"), IOStandard("TMDS_33")), - Subsignal("scl", Pins("V9"), IOStandard("I2C")), - Subsignal("sda", Pins("T9"), IOStandard("I2C")), - Subsignal("hpd_notif", Pins("R8"), IOStandard("LVTTL")), - ), - - ("spiflash", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("mosi", Pins("T13")), - Subsignal("miso", Pins("R13"), Misc("PULLUP")), - Subsignal("wp", Pins("T14")), - Subsignal("hold", Pins("V14")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - ("spiflash2x", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("dq", Pins("T13 R13"), Misc("PULLUP")), - Subsignal("wp", Pins("T14")), - Subsignal("hold", Pins("V14")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - ("spiflash4x", 0, - Subsignal("cs_n", Pins("V3")), - Subsignal("clk", Pins("R15")), - Subsignal("dq", Pins("T13 R13 T14 V14"), Misc("PULLUP")), - IOStandard("LVTTL"), Misc("SLEW=FAST") - ), - - ("mmc", 0, - Subsignal("clk", Pins("A3")), - Subsignal("cmd", Pins("B3"), Misc("PULLUP")), - Subsignal("dat", Pins("B4 A4 B2 A2"), Misc("PULLUP")), - IOStandard("SDIO") - ), - - ("mmc_spi", 0, - Subsignal("cs_n", Pins("A2"), Misc("PULLUP")), - Subsignal("clk", Pins("A3")), - Subsignal("mosi", Pins("B3")), - Subsignal("miso", Pins("B4"), Misc("PULLUP")), - IOStandard("SDIO") - ), - - ("audio", 0, - Subsignal("l", Pins("R7"), Misc("SLEW=SLOW")), - Subsignal("r", Pins("T7"), Misc("SLEW=SLOW")), - IOStandard("LVTTL"), - ), - - ("pmod", 0, - Subsignal("d", Pins("D9 C8 D6 C4 B11 C9 D8 C6")), - IOStandard("LVTTL") - ), - - ("ddram_clock", 0, - Subsignal("p", Pins("G3")), - Subsignal("n", Pins("G1")), - IOStandard("MOBILE_DDR") - ), - - ("ddram", 0, - Subsignal("a", Pins("J7 J6 H5 L7 F3 H4 H3 H6 D2 D1 F4 D3 G6")), - Subsignal("ba", Pins("F2 F1")), - Subsignal("cke", Pins("H7")), - Subsignal("ras_n", Pins("L5")), - Subsignal("cas_n", Pins("K5")), - Subsignal("we_n", Pins("E3")), - Subsignal("dq", Pins("L2 L1 K2 K1 H2 H1 J3 J1 M3 M1 N2 N1 T2 T1 U2 U1")), - Subsignal("dqs", Pins("L4 P2")), - Subsignal("dm", Pins("K3 K4")), - IOStandard("MOBILE_DDR") - ) -] - -_connectors = [ - ("A", "U18 T17 P17 P16 N16 N17 M16 L15 L17 K15 K17 J16 H15 H18 F18 D18"), - ("B", "C18 E18 G18 H16 J18 K18 K16 L18 L16 M18 N18 N15 P15 P18 T18 U17"), - ("C", "F17 F16 E16 G16 F15 G14 F14 H14 H13 J13 G13 H12 K14 K13 K12 L12"), -] - - -class Platform(XilinxPlatform): - identifier = 0x5049 - default_clk_name = "clk50" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx45-csg324-3", _io, _connectors) - self.toolchain.bitgen_opt += " -g Compress -g ConfigRate:6" - - def create_programmer(self): - return XC3SProg("papilio", "bscan_spi_lx45_csg324.bit") diff --git a/migen/build/platforms/rhino.py b/migen/build/platforms/rhino.py deleted file mode 100644 index 0cb99596..00000000 --- a/migen/build/platforms/rhino.py +++ /dev/null @@ -1,142 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("user_led", 0, Pins("Y3")), - ("user_led", 1, Pins("Y1")), - ("user_led", 2, Pins("W2")), - ("user_led", 3, Pins("W1")), - ("user_led", 4, Pins("V3")), - ("user_led", 5, Pins("V1")), - ("user_led", 6, Pins("U2")), - ("user_led", 7, Pins("U1")), - - ("clk100", 0, - Subsignal("p", Pins("B14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("n", Pins("A14"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")) - ), - - ("gpio", 0, Pins("R8")), - - ("gpmc", 0, - Subsignal("clk", Pins("R26")), - Subsignal("a", Pins("N17 N18 L23 L24 N19 N20 N21 N22 P17 P19")), - Subsignal("d", Pins("N23 N24 R18 R19 P21 P22 R20 R21 P24 P26 R23 R24 T22 T23 U23 R25")), - Subsignal("we_n", Pins("W26")), - Subsignal("oe_n", Pins("AA25")), - Subsignal("ale_n", Pins("AA26")), - Subsignal("wait", Pins("AD26")), # WAIT1/BUSY0 - IOStandard("LVCMOS33")), - # Warning: CS are numbered 1-7 on ARM side and 0-6 on FPGA side. - # Numbers here are given on the FPGA side. - ("gpmc_ce_n", 0, Pins("V23"), IOStandard("LVCMOS33")), # nCS0 - ("gpmc_ce_n", 1, Pins("U25"), IOStandard("LVCMOS33")), # nCS1 - ("gpmc_ce_n", 2, Pins("W25"), IOStandard("LVCMOS33")), # nCS6 - ("gpmc_dmareq_n", 0, Pins("T24"), IOStandard("LVCMOS33")), # nCS2 - ("gpmc_dmareq_n", 1, Pins("T26"), IOStandard("LVCMOS33")), # nCS3 - ("gpmc_dmareq_n", 2, Pins("V24"), IOStandard("LVCMOS33")), # nCS4 - ("gpmc_dmareq_n", 3, Pins("V26"), IOStandard("LVCMOS33")), # nCS5 - - # FMC150 - ("fmc150_ctrl", 0, - Subsignal("spi_sclk", Pins("AE5")), - Subsignal("spi_data", Pins("AF5")), - - Subsignal("adc_sdo", Pins("U13")), - Subsignal("adc_en_n", Pins("AA15")), - Subsignal("adc_reset", Pins("V13")), - - Subsignal("cdce_sdo", Pins("AA8")), - Subsignal("cdce_en_n", Pins("Y9")), - Subsignal("cdce_reset_n", Pins("AB7")), - Subsignal("cdce_pd_n", Pins("AC6")), - Subsignal("cdce_pll_status", Pins("W7")), - Subsignal("cdce_ref_en", Pins("W8")), - - Subsignal("dac_sdo", Pins("W9")), - Subsignal("dac_en_n", Pins("W10")), - - Subsignal("mon_sdo", Pins("AC5")), - Subsignal("mon_en_n", Pins("AD6")), - Subsignal("mon_reset_n", Pins("AF6")), - Subsignal("mon_int_n", Pins("AD5")), - - Subsignal("pg_c2m", Pins("AA23"), IOStandard("LVCMOS33")) - ), - ("ti_dac", 0, # DAC3283 - Subsignal("dat_p", Pins("AA10 AA9 V11 Y11 W14 Y12 AD14 AE13"), IOStandard("LVDS_25")), - Subsignal("dat_n", Pins("AB11 AB9 V10 AA11 Y13 AA12 AF14 AF13"), IOStandard("LVDS_25")), - Subsignal("frame_p", Pins("AB13"), IOStandard("LVDS_25")), - Subsignal("frame_n", Pins("AA13"), IOStandard("LVDS_25")), - Subsignal("txenable", Pins("AB15"), IOStandard("LVCMOS25")) - ), - ("ti_adc", 0, # ADS62P49 - Subsignal("dat_a_p", Pins("AB14 Y21 W20 AB22 V18 W17 AA21")), - Subsignal("dat_a_n", Pins("AC14 AA22 Y20 AC22 W19 W18 AB21")), - Subsignal("dat_b_p", Pins("Y17 U15 AA19 W16 AA18 Y15 V14")), - Subsignal("dat_b_n", Pins("AA17 V16 AB19 Y16 AB17 AA16 V15")), - IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE") - ), - ("fmc150_clocks", 0, - Subsignal("dac_clk_p", Pins("V12"), IOStandard("LVDS_25")), - Subsignal("dac_clk_n", Pins("W12"), IOStandard("LVDS_25")), - Subsignal("adc_clk_p", Pins("AE15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("adc_clk_n", Pins("AF15"), IOStandard("LVDS_25"), Misc("DIFF_TERM=TRUE")), - Subsignal("clk_to_fpga", Pins("W24"), IOStandard("LVCMOS25")) - ), - - ("fmc150_ext_trigger", 0, Pins("U26")), - - # Vermeer radar testbed - # Switch controller - ("pca9555", 0, - Subsignal("sda", Pins("C13")), - Subsignal("scl", Pins("G8")), - IOStandard("LVCMOS33") - ), - # TX path - ("pe43602", 0, - Subsignal("d", Pins("H8")), - Subsignal("clk", Pins("B3")), - Subsignal("le", Pins("F7")), - IOStandard("LVCMOS33") - ), - ("rfmd2081", 0, - Subsignal("enx", Pins("E5")), - Subsignal("sclk", Pins("G6")), - Subsignal("sdata", Pins("F5")), - Subsignal("locked", Pins("E6")), - IOStandard("LVCMOS33") - ), - # RX path - ("lmh6521", 0, - Subsignal("scsb", Pins("C5")), - Subsignal("sclk", Pins("G10")), - Subsignal("sdi", Pins("D5")), - Subsignal("sdo", Pins("F9")), - IOStandard("LVCMOS33") - ), - ("lmh6521", 1, - Subsignal("scsb", Pins("E10")), - Subsignal("sclk", Pins("A4")), - Subsignal("sdi", Pins("B4")), - Subsignal("sdo", Pins("H10")), - IOStandard("LVCMOS33") - ), - ("rffc5071", 0, - Subsignal("enx", Pins("A2")), - Subsignal("sclk", Pins("G9")), - Subsignal("sdata", Pins("H9")), - Subsignal("locked", Pins("A3")), - IOStandard("LVCMOS33") - ) -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx150t-fgg676-3", _io) diff --git a/migen/build/platforms/roach.py b/migen/build/platforms/roach.py deleted file mode 100644 index 19c1ccb4..00000000 --- a/migen/build/platforms/roach.py +++ /dev/null @@ -1,35 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("epb", 0, - Subsignal("cs_n", Pins("K13")), - Subsignal("r_w_n", Pins("AF20")), - Subsignal("be_n", Pins("AF14 AF18")), - Subsignal("oe_n", Pins("AF21")), - Subsignal("addr", Pins("AE23 AE22 AG18 AG12 AG15 AG23 AF19 AE12 AG16 AF13 AG20 AF23", - "AH17 AH15 L20 J22 H22 L15 L16 K22 K21 K16 J15")), - Subsignal("addr_gp", Pins("L21 G22 K23 K14 L14 J12")), - Subsignal("data", Pins("AF15 AE16 AE21 AD20 AF16 AE17 AE19 AD19 AG22 AH22 AH12 AG13", - "AH20 AH19 AH14 AH13")), - Subsignal("rdy", Pins("K12")), - IOStandard("LVCMOS33") - ), - ("roach_clocks", 0, - Subsignal("epb_clk", Pins("AH18"), IOStandard("LVCMOS33")), - Subsignal("sys_clk_n", Pins("H13")), - Subsignal("sys_clk_p", Pins("J14")), - Subsignal("aux0_clk_p", Pins("G15")), - Subsignal("aux0_clk_n", Pins("G16")), - Subsignal("aux1_clk_p", Pins("H14")), - Subsignal("aux1_clk_n", Pins("H15")), - Subsignal("dly_clk_n", Pins("J17")), - Subsignal("dly_clk_p", Pins("J16")), - ), -] - - -class Platform(XilinxPlatform): - def __init__(self): - XilinxPlatform.__init__(self, "xc5vsx95t-ff1136-1", _io) diff --git a/migen/build/platforms/usrp_b100.py b/migen/build/platforms/usrp_b100.py deleted file mode 100644 index d2541263..00000000 --- a/migen/build/platforms/usrp_b100.py +++ /dev/null @@ -1,152 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("clk64", 0, - Subsignal("p", Pins("R7")), - Subsignal("n", Pins("T7")), - IOStandard("LVDS_33"), - Misc("DIFF_TERM=TRUE"), - ), - - ("pps", 0, Pins("M14"), Misc("TIG")), - ("reset_n", 0, Pins("D5"), Misc("TIG")), - ("codec_reset", 0, Pins("B14")), - # recycles fpga_cfg_cclk for reset from fw - ("ext_reset", 0, Pins("R14")), - - ("i2c", 0, - Subsignal("sda", Pins("T13")), - Subsignal("scl", Pins("R13")), - ), - - ("cgen", 0, - Subsignal("st_ld", Pins("M13")), - Subsignal("st_refmon", Pins("J14")), - Subsignal("st_status", Pins("P6")), - Subsignal("ref_sel", Pins("T2")), - Subsignal("sync_b", Pins("H15")), - ), - - ("fx2_ifclk", 0, Pins("T8")), - ("fx2_gpif", 0, - Subsignal("d", Pins("P8 P9 N9 T9 R9 P11 P13 N12 " - "T3 R3 P5 N6 T6 T5 N8 P7")), - Subsignal("ctl", Pins("M7 M9 M11 P12")), - Subsignal("slwr", Pins("T4")), # rdy0 - Subsignal("slrd", Pins("R5")), # rdy1 - # Subsignal("rdy2", Pins("T10")), - # Subsignal("rdy3", Pins("N11")), - # Subsignal("cs", Pins("P12")), - Subsignal("sloe", Pins("R11")), - Subsignal("pktend", Pins("P10")), - Subsignal("adr", Pins("T11 H16")), - ), - - ("user_led", 0, Pins("P4"), Misc("TIG")), - ("user_led", 1, Pins("N4"), Misc("TIG")), - ("user_led", 2, Pins("R2"), Misc("TIG")), - - ("debug_clk", 0, Pins("K15 K14")), - ("debug", 0, Pins( - "K16 J16 C16 C15 E13 D14 D16 D15 " - "E14 F13 G13 F14 E16 F15 H13 G14 " - "G16 F16 J12 J13 L14 L16 M15 M16 " - "L13 K13 P16 N16 R15 P15 N13 N14")), - - ("adc", 0, - Subsignal("sync", Pins("D10")), - Subsignal("d", Pins("A4 B3 A3 D9 C10 A9 C9 D8 " - "C8 B8 A8 B15")), - ), - ("dac", 0, - Subsignal("blank", Pins("K1")), - Subsignal("sync", Pins("J2")), - Subsignal("d", Pins("J1 H3 J3 G2 H1 N3 M4 R1 " - "P2 P1 M1 N1 M3 L4")), - ), - ("codec_spi", 0, - Subsignal("sclk", Pins("K3")), - Subsignal("sen", Pins("D13")), - Subsignal("mosi", Pins("C13")), - Subsignal("miso", Pins("G4")), - ), - - ("aux_spi", 0, - Subsignal("sen", Pins("C12")), - Subsignal("sclk", Pins("D12")), - Subsignal("miso", Pins("J5")), - ), - ("rx_io", 0, Pins("D7 C6 A6 B6 E9 A7 C7 B10 " - "A10 C11 A11 D11 B12 A12 A14 A13")), - ("tx_io", 0, Pins("K4 L3 L2 F1 F3 G3 E3 E2 " - "E4 F4 D1 E1 D4 D3 C2 C1")), - ("rx_spi", 0, - Subsignal("miso", Pins("E6")), - Subsignal("sen", Pins("B4")), - Subsignal("mosi", Pins("A5")), - Subsignal("sclk", Pins("C5")), - ), - ("tx_spi", 0, - Subsignal("miso", Pins("J4")), - Subsignal("sen", Pins("N2")), - Subsignal("mosi", Pins("L1")), - Subsignal("sclk", Pins("G1")), - ), - - # these are just for information. do not request. - ("mystery_bus", 0, Pins("C4 E7")), - ("fpga_cfg", - Subsignal("din", Pins("T14")), - Subsignal("cclk", Pins("R14")), - Subsignal("init_b", Pins("T12")), - Subsignal("prog_b", Pins("A2")), - Subsignal("done", Pins("T15")), - ), - ("jtag", - Subsignal("tms", Pins("B2")), - Subsignal("tdo", Pins("B16")), - Subsignal("tdi", Pins("B1")), - Subsignal("tck", Pins("A15")), - ), -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk64" - default_clk_period = 15.625 - - def __init__(self): - XilinxPlatform.__init__(self, "xc3s1400a-ft256-4", _io) - self.toolchain.bitgen_opt = "-g LCK_cycle:6 -g Binary:Yes -w -g UnusedPin:PullUp" - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - self.add_platform_command(""" -TIMESPEC TS_Pad2Pad = FROM PADS TO PADS 7 ns; -""") - - try: - ifclk = self.lookup_request("fx2_ifclk") - gpif = self.lookup_request("fx2_gpif") - for i, d in [(gpif.d, "in"), (gpif.d, "out"), - (gpif.ctl, "in"), (gpif.adr, "out"), - (gpif.slwr, "out"), (gpif.sloe, "out"), - (gpif.slrd, "out"), (gpif.pktend, "out")]: - if len(i) > 1: - q = "(*)" - else: - q = "" - self.add_platform_command(""" -INST "{i}%s" TNM = gpif_net_%s; -""" % (q, d), i=i) - self.add_platform_command(""" -NET "{ifclk}" TNM_NET = "GRPifclk"; -TIMESPEC "TSifclk" = PERIOD "GRPifclk" 20833 ps HIGH 50%; -TIMEGRP "gpif_net_in" OFFSET = IN 5 ns VALID 10 ns BEFORE "{ifclk}" RISING; -TIMEGRP "gpif_net_out" OFFSET = OUT 7 ns AFTER "{ifclk}" RISING; -""", ifclk=ifclk) - except ConstraintError: - pass diff --git a/migen/build/platforms/zedboard.py b/migen/build/platforms/zedboard.py deleted file mode 100644 index b5d3dcc2..00000000 --- a/migen/build/platforms/zedboard.py +++ /dev/null @@ -1,145 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -# Bank 34 and 35 voltage depend on J18 jumper setting -_io = [ - ("clk100", 0, Pins("Y9"), IOStandard("LVCMOS33")), - - ("user_btn", 0, Pins("P16"), IOStandard("LVCMOS18")), # center - ("user_btn", 1, Pins("R16"), IOStandard("LVCMOS18")), # down - ("user_btn", 2, Pins("N15"), IOStandard("LVCMOS18")), # left - ("user_btn", 3, Pins("R18"), IOStandard("LVCMOS18")), # right - ("user_btn", 4, Pins("T18"), IOStandard("LVCMOS18")), # up - - ("user_sw", 0, Pins("F22"), IOStandard("LVCMOS18")), - ("user_sw", 1, Pins("G22"), IOStandard("LVCMOS18")), - ("user_sw", 2, Pins("H22"), IOStandard("LVCMOS18")), - ("user_sw", 3, Pins("F21"), IOStandard("LVCMOS18")), - ("user_sw", 4, Pins("H19"), IOStandard("LVCMOS18")), - ("user_sw", 5, Pins("H18"), IOStandard("LVCMOS18")), - ("user_sw", 6, Pins("H17"), IOStandard("LVCMOS18")), - ("user_sw", 7, Pins("M15"), IOStandard("LVCMOS18")), - - ("user_led", 0, Pins("T22"), IOStandard("LVCMOS33")), - ("user_led", 1, Pins("T21"), IOStandard("LVCMOS33")), - ("user_led", 2, Pins("U22"), IOStandard("LVCMOS33")), - ("user_led", 3, Pins("U21"), IOStandard("LVCMOS33")), - ("user_led", 4, Pins("V22"), IOStandard("LVCMOS33")), - ("user_led", 5, Pins("W22"), IOStandard("LVCMOS33")), - ("user_led", 6, Pins("U19"), IOStandard("LVCMOS33")), - ("user_led", 7, Pins("U14"), IOStandard("LVCMOS33")), - - # A - ("pmod", 0, Pins("Y11 AA11 Y10 AA9 AB11 AB10 AB9 AA8"), - IOStandard("LVCMOS33")), - # B - ("pmod", 1, Pins("W12 W11 V10 W8 V12 W10 V9 V8"), - IOStandard("LVCMOS33")), - # C - ("pmod", 2, - Subsignal("n", Pins("AB6 AA4 T6 U4")), - Subsignal("p", Pins("AB7 Y4 R6 T4")), - IOStandard("LVCMOS33")), - # D - ("pmod", 3, - Subsignal("n", Pins("W7 V4 W5 U5")), - Subsignal("p", Pins("V7 V5 W6 U6")), - IOStandard("LVCMOS33")), - - ("audio", 0, - Subsignal("adr", Pins("AB1 Y5")), - Subsignal("gpio", Pins("Y8 AA7 AA6 Y6")), - Subsignal("mclk", Pins("AB2")), - Subsignal("sck", Pins("AB4")), - Subsignal("sda", Pins("AB5")), - IOStandard("LVCMOS33")), - - ("oled", 0, - Subsignal("dc", Pins("U10")), - Subsignal("res", Pins("U9")), - Subsignal("sclk", Pins("AB12")), - Subsignal("sdin", Pins("AA12")), - Subsignal("vbat", Pins("U11")), - Subsignal("vdd", Pins("U12")), - IOStandard("LVCMOS33")), - - ("hdmi", 0, - Subsignal("clk", Pins("W18")), - Subsignal("d", Pins( - "Y13 AA13 AA14 Y14 AB15 AB16 AA16 AB17 " - "AA17 Y15 W13 W15 V15 U17 V14 V13")), - Subsignal("de", Pins("U16")), - Subsignal("hsync", Pins("V17")), - Subsignal("vsync", Pins("W17")), - Subsignal("int", Pins("W16")), - Subsignal("scl", Pins("AA18")), - Subsignal("sda", Pins("Y16")), - Subsignal("spdif", Pins("U15")), - Subsignal("spdifo", Pins("Y18")), - IOStandard("LVCMOS33")), - - ("netic16", 0, - Subsignal("w20", Pins("W20")), - Subsignal("w21", Pins("W21")), - IOStandard("LVCMOS33")), - - ("vga", 0, - Subsignal("r", Pins("V20 U20 V19 V18")), - Subsignal("g", Pins("AB22 AA22 AB21 AA21")), - Subsignal("b", Pins("Y21 Y20 AB20 AB19")), - Subsignal("hsync_n", Pins("AA19")), - Subsignal("vsync_n", Pins("Y19")), - IOStandard("LVCMOS33")), - - ("usb_otg", 0, - Subsignal("vbusoc", Pins("L16")), - Subsignal("reset_n", Pins("G17")), - IOStandard("LVCMOS18")), - - ("pudc_b", 0, Pins("K16"), IOStandard("LVCMOS18")), - - ("xadc", 0, - Subsignal("gio", Pins("H15 R15 K15 J15")), - Subsignal("ad0_n", Pins("E16")), - Subsignal("ad0_p", Pins("F16")), - Subsignal("ad8_n", Pins("D17")), - Subsignal("ad8_p", Pins("D16")), - IOStandard("LVCMOS18")), - - ("fmc_clocks", 0, - Subsignal("clk0_n", Pins("L19")), - Subsignal("clk0_p", Pins("L18")), - Subsignal("clk1_n", Pins("C19")), - Subsignal("clk1_p", Pins("D18")), - IOStandard("LVCMOS18")), - - ("fmc", 0, - Subsignal("scl", Pins("R7")), - Subsignal("sda", Pins("U7")), - - Subsignal("prsnt", Pins("AB14")), - - # 0, 1, 17, 18 can be clock signals - Subsignal("la_n", Pins( - "M20 N20 P18 P22 M22 K18 L22 T17 " - "J22 R21 T19 N18 P21 M17 K20 J17 " - "K21 B20 C20 G16 G21 E20 F19 D15 " - "A19 C22 E18 D21 A17 C18 B15 B17 " - "A22 B22")), - Subsignal("la_p", Pins( - "M19 N19 P17 N22 M21 J18 L21 T16 " - "J21 R20 R19 N17 P20 L17 K19 J16 " - "J20 B19 D20 G15 G20 E19 G19 E15 " - "A18 D22 F18 E21 A16 C17 C15 B16 " - "A21 B21")), - IOStandard("LVCMOS18")), -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk100" - default_clk_period = 10 - - def __init__(self): - XilinxPlatform.__init__(self, "xc7z020-clg484-1", _io) diff --git a/migen/build/platforms/ztex_115d.py b/migen/build/platforms/ztex_115d.py deleted file mode 100644 index 253a121c..00000000 --- a/migen/build/platforms/ztex_115d.py +++ /dev/null @@ -1,110 +0,0 @@ -from migen.build.generic_platform import * -from migen.build.xilinx import XilinxPlatform - - -_io = [ - ("clk_fx", 0, Pins("L22"), IOStandard("LVCMOS33")), - ("clk_if", 0, Pins("K20"), IOStandard("LVCMOS33")), - ("rst", 0, Pins("A18")), - # PROG_B and DONE: AA1 U16 - - ("fx2", 0, - Subsignal("sloe", Pins("U15"), Drive(12)), # M1 - Subsignal("slrd", Pins("N22"), Drive(12)), - Subsignal("slwr", Pins("M22"), Drive(12)), - Subsignal("pktend", Pins("AB5"), Drive(12)), # CSO - Subsignal("fifoadr", Pins("W17 Y18"), Drive(12)), # CCLK M0 - Subsignal("cont", Pins("G20")), - Subsignal("fd", Pins("Y17 V13 W13 AA8 AB8 W6 Y6 Y9 " - "V21 V22 U20 U22 R20 R22 P18 P19")), - Subsignal("flag", Pins("F20 F19 F18 AB17")), # - - - CSI/MOSI - Subsignal("rdy25", Pins("M21 K21 K22 J21")), - Subsignal("ctl35", Pins("D19 E20 N20")), - Subsignal("int45", Pins("C18 V17")), - Subsignal("pc", Pins("G20 T10 V5 AB9 G19 H20 H19 H18")), - # - DOUT/BUSY INIT_B RDWR_B DO CS CLK DI - IOStandard("LVCMOS33")), - - ("mm", 0, - Subsignal("a", Pins("M20 M19 M18 N19 T19 T21 T22 R19 ", - "P20 P21 P22 J22 H21 H22 G22 F21")), - Subsignal("d", Pins("D20 C20 C19 B21 B20 J19 K19 L19"), Drive(2)), - Subsignal("wr_n", Pins("C22")), - Subsignal("rd_n", Pins("D21")), - Subsignal("psen_n", Pins("D22")), - IOStandard("LVCMOS33")), - - ("serial", 0, - Subsignal("tx", Pins("B22"), Misc("SLEW=QUIETIO")), - Subsignal("rx", Pins("A21"), Misc("PULLDOWN")), - IOStandard("LVCMOS33")), - - ("ddram_clock", 0, - Subsignal("p", Pins("F2"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("n", Pins("F1"), Misc("OUT_TERM=UNTUNED_50")), - IOStandard("SSTL18_II")), - - ("ddram", 0, - Subsignal("dqs", Pins("L3 T2"), IOStandard("SSTL18_II"), # DIFF_ - Misc("IN_TERM=NONE")), - Subsignal("dqs_n", Pins("L1 T1"), IOStandard("SSTL18_II"), # DIFF_ - Misc("IN_TERM=NONE")), - Subsignal("dm", Pins("H1 H2"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("dq", Pins("M1 M2 J1 K2 J3 K1 N3 N1 " - "U1 U3 P1 R3 P2 R1 V2 V1"), Misc("IN_TERM=NONE")), - Subsignal("ras_n", Pins("N4"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("cas_n", Pins("P3"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("a", Pins("M5 K6 B1 J4 L4 K3 M4 K5 G3 G1 K4 C3 C1"), - Misc("OUT_TERM=UNTUNED_50")), - Subsignal("ba", Pins("E3 E1 D1"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("cke", Pins("J6"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("cs_n", Pins("H6")), # NC! - Subsignal("odt", Pins("M3"), Misc("OUT_TERM=UNTUNED_50")), - Subsignal("we_n", Pins("D2")), - Subsignal("rzq", Pins("AA2")), - Subsignal("zio", Pins("Y2")), - IOStandard("SSTL18_II")), - - ("i2c", 0, - Subsignal("scl", Pins("F22")), - Subsignal("sda", Pins("E22")), - IOStandard("LVCMOS33")), - - ("sd", 0, - Subsignal("sck", Pins("H11")), - Subsignal("d3", Pins("H14")), - Subsignal("d", Pins("P10")), - Subsignal("d1", Pins("T18")), - Subsignal("d2", Pins("R17")), - Subsignal("cmd", Pins("H13")), - IOStandard("LVCMOS33")), - -] - - -class Platform(XilinxPlatform): - default_clk_name = "clk_if" - default_clk_period = 20 - - def __init__(self): - XilinxPlatform.__init__(self, "xc6slx150-3csg484", _io) - self.add_platform_command(""" -CONFIG VCCAUX = "2.5"; -""") - - def do_finalize(self, fragment): - XilinxPlatform.do_finalize(self, fragment) - - try: - clk_if = self.lookup_request("clk_if") - clk_fx = self.lookup_request("clk_fx") - self.add_platform_command(""" -NET "{clk_if}" TNM_NET = "GRPclk_if"; -NET "{clk_fx}" TNM_NET = "GRPclk_fx"; -TIMESPEC "TSclk_fx" = PERIOD "GRPclk_fx" 20.83333 ns HIGH 50%; -TIMESPEC "TSclk_if" = PERIOD "GRPclk_if" 20 ns HIGH 50%; -TIMESPEC "TSclk_fx2if" = FROM "GRPclk_fx" TO "GRPclk_if" 3 ns DATAPATHONLY; -TIMESPEC "TSclk_if2fx" = FROM "GRPclk_if" TO "GRPclk_fx" 3 ns DATAPATHONLY; -""", clk_if=clk_if, clk_fx=clk_fx) - except ConstraintError: - pass diff --git a/migen/build/sim/__init__.py b/migen/build/sim/__init__.py deleted file mode 100644 index adbba1c4..00000000 --- a/migen/build/sim/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from migen.build.sim.platform import SimPlatform diff --git a/migen/build/sim/common.py b/migen/build/sim/common.py deleted file mode 100644 index 38741fd4..00000000 --- a/migen/build/sim/common.py +++ /dev/null @@ -1 +0,0 @@ -sim_special_overrides = {} diff --git a/migen/build/sim/dut_tb.cpp b/migen/build/sim/dut_tb.cpp deleted file mode 100644 index 0e8dac7e..00000000 --- a/migen/build/sim/dut_tb.cpp +++ /dev/null @@ -1,399 +0,0 @@ -// This file is Copyright (c) 2015 Florent Kermarrec -// License: BSD -#include "Vdut.h" -#include "verilated.h" -#include "verilated_vcd_c.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* ios */ - -#ifdef SERIAL_SOURCE_STB -#define WITH_SERIAL -#endif - -#ifdef ETH_SOURCE_STB -#define WITH_ETH -#endif - -#define MAX(a,b) (((a)>(b))?(a):(b)) -#define MIN(a,b) (((a)<(b))?(a):(b)) - -int trace = 0; - -vluint64_t main_time = 0; -double sc_time_stamp() -{ - return main_time; -} - -/* Sim struct */ -struct sim { - bool run; - - unsigned int tick; - clock_t start; - clock_t end; - float speed; - -#ifdef WITH_SERIAL_PTY - char serial_dev[64]; - int serial_fd; - unsigned char serial_rx_data; - unsigned char serial_tx_data; -#endif -#ifdef WITH_ETH - const char *eth_dev; - const char *eth_tap; - int eth_fd; - unsigned char eth_txbuffer[2048]; - unsigned char eth_rxbuffer[2048]; - int eth_txbuffer_len; - int eth_rxbuffer_len; - int eth_rxbuffer_pos; - int eth_last_source_stb; -#endif -}; - -/* Serial functions */ -#ifndef WITH_SERIAL_PTY -struct termios orig_termios; - -void reset_terminal_mode(void) -{ - tcsetattr(0, TCSANOW, &orig_termios); -} - -void set_conio_terminal_mode(void) -{ - struct termios new_termios; - - /* take two copies - one for now, one for later */ - tcgetattr(0, &orig_termios); - memcpy(&new_termios, &orig_termios, sizeof(new_termios)); - - /* register cleanup handler, and set the new terminal mode */ - atexit(reset_terminal_mode); - cfmakeraw(&new_termios); - tcsetattr(0, TCSANOW, &new_termios); -} - -int kbhit(void) -{ - struct timeval tv = { 0L, 0L }; - fd_set fds; - FD_ZERO(&fds); - FD_SET(0, &fds); - return select(1, &fds, NULL, NULL, &tv); -} - -int getch(void) -{ - int r; - unsigned char c; - if((r = read(0, &c, sizeof(c))) < 0) { - return r; - } else { - return c; - } -} -#endif - -/* Ethernet functions */ -/* create tap: - openvpn --mktun --dev tap0 - ifconfig tap0 192.168.0.14 up - mknod /dev/net/tap0 c 10 200 - delete tap: - openvpn --rmtun --dev tap0 */ -#ifdef WITH_ETH -void eth_init(struct sim *s, const char *dev, const char*tap) -{ - s->eth_txbuffer_len = 0; - s->eth_rxbuffer_len = 0; - s->eth_rxbuffer_pos = 0; - s->eth_last_source_stb = 0; - s->eth_dev = dev; - s->eth_tap = tap; -} - -void eth_open(struct sim *s) -{ - - struct ifreq ifr; - s->eth_fd = open (s->eth_dev, O_RDWR); - if(s->eth_fd < 0) { - fprintf(stderr, " Could not open dev %s\n", s->eth_dev); - return; - } - - memset(&ifr, 0, sizeof(ifr)); - ifr.ifr_flags = IFF_TAP | IFF_NO_PI; - strncpy(ifr.ifr_name, s->eth_tap, IFNAMSIZ); - - if(ioctl(s->eth_fd, TUNSETIFF, (void *) &ifr) < 0) { - fprintf(stderr, " Could not set %s\n", s->eth_tap); - close(s->eth_fd); - } - return; -} - -int eth_close(struct sim *s) -{ - if(s->eth_fd < 0) - close(s->eth_fd); -} - -void eth_write(struct sim *s, unsigned char *buf, int len) -{ - write(s->eth_fd, buf, len); -} - -int eth_read(struct sim *s, unsigned char *buf) -{ - - struct pollfd fds[1]; - int n; - int len; - - fds[0].fd = s->eth_fd; - fds[0].events = POLLIN; - - n = poll(fds, 1, 0); - if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) { - len = read(s->eth_fd, buf, 1532); - } else { - len = 0; - } - return len; -} -#endif - -Vdut* dut; -VerilatedVcdC* tfp; - -#ifndef WITH_SERIAL_PTY -int console_service(struct sim *s) -{ - /* fpga --> console */ - SERIAL_SOURCE_ACK = 1; - if(SERIAL_SOURCE_STB == 1) { - if(SERIAL_SOURCE_DATA == '\n') - putchar('\r'); - putchar(SERIAL_SOURCE_DATA); - fflush(stdout); - } - - /* console --> fpga */ - SERIAL_SINK_STB = 0; - if(s->tick%(1000) == 0) { - if(kbhit()) { - char c = getch(); - if(c == 27 && !kbhit()) { - printf("\r\n"); - return -1; - } else { - SERIAL_SINK_STB = 1; - SERIAL_SINK_DATA = c; - } - } - } - return 0; -} -#else -void console_init(struct sim *s) -{ - FILE *f; - f = fopen("/tmp/simserial","r"); - fscanf(f, "%[^\n]", s->serial_dev); - fclose(f); - return; -} - -void console_open(struct sim *s) -{ - s->serial_fd = open(s->serial_dev, O_RDWR); - if(s->serial_fd < 0) { - fprintf(stderr, " Could not open dev %s\n", s->serial_dev); - return; - } - return; -} - -int console_close(struct sim *s) -{ - if(s->serial_fd < 0) - close(s->serial_fd); -} - -void console_write(struct sim *s, unsigned char *buf, int len) -{ - write(s->serial_fd, buf, len); -} - -int console_read(struct sim *s, unsigned char *buf) -{ - struct pollfd fds[1]; - int n; - int len; - - fds[0].fd = s->serial_fd; - fds[0].events = POLLIN; - - n = poll(fds, 1, 0); - if((n > 0) && ((fds[0].revents & POLLIN) == POLLIN)) { - len = read(s->serial_fd, buf, 1); - } else { - len = 0; - } - return len; -} - -int console_service(struct sim *s) -{ - /* fpga --> console */ - SERIAL_SOURCE_ACK = 1; - if(SERIAL_SOURCE_STB == 1) { - s->serial_tx_data = SERIAL_SOURCE_DATA; - console_write(s, &(s->serial_tx_data), 1); - } - - /* console --> fpga */ - SERIAL_SINK_STB = 0; - if(console_read(s, &(s->serial_rx_data))) - { - SERIAL_SINK_STB = 1; - SERIAL_SINK_DATA = s->serial_rx_data; - } - return 0; -} -#endif - -#ifdef WITH_ETH -int ethernet_service(struct sim *s) { - /* fpga --> tap */ - ETH_SOURCE_ACK = 1; - if(ETH_SOURCE_STB == 1) { - s->eth_txbuffer[s->eth_txbuffer_len] = ETH_SOURCE_DATA; - s->eth_txbuffer_len++; - } else { - if(s->eth_last_source_stb) { - eth_write(s, s->eth_txbuffer, s->eth_txbuffer_len); - s->eth_txbuffer_len = 0; - } - } - s->eth_last_source_stb = ETH_SOURCE_STB; - - /* tap --> fpga */ - if(s->eth_rxbuffer_len == 0) { - ETH_SINK_STB = 0; - s->eth_rxbuffer_pos = 0; - s->eth_rxbuffer_len = eth_read(s, s->eth_rxbuffer); - } else { - if(s->eth_rxbuffer_pos < MAX(s->eth_rxbuffer_len, 60)) { - ETH_SINK_STB = 1; - ETH_SINK_DATA = s->eth_rxbuffer[s->eth_rxbuffer_pos]; - s->eth_rxbuffer_pos++; - } else { - ETH_SINK_STB = 0; - s->eth_rxbuffer_len = 0; - memset(s->eth_rxbuffer, 0, 1532); - } - } -} -#endif - -void sim_tick(struct sim *s) -{ - SYS_CLK = s->tick%2; - dut->eval(); - if(trace) - tfp->dump(s->tick); - s->tick++; -} - -void sim_init(struct sim *s) -{ - int i; - s->tick = 0; -#ifdef SYS_RST - SYS_RST = 1; - SYS_CLK = 0; - for (i=0; i<8; i++) - sim_tick(s); - SYS_RST = 0; -#endif - s->start = clock(); -} - -int main(int argc, char **argv, char **env) -{ - float speed; - -#ifndef WITH_SERIAL_PTY - set_conio_terminal_mode(); -#endif - - Verilated::commandArgs(argc, argv); - dut = new Vdut; - - Verilated::traceEverOn(true); - tfp = new VerilatedVcdC; - dut->trace(tfp, 99); - tfp->open("dut.vcd"); - - struct sim s; - sim_init(&s); - -#ifdef WITH_SERIAL_PTY - console_init(&s); - console_open(&s); -#endif - -#ifdef WITH_ETH - eth_init(&s, "/dev/net/tap0", "tap0"); // XXX get this from /tmp/simethernet - eth_open(&s); -#endif - - s.run = true; - while(s.run) { - sim_tick(&s); - if(SYS_CLK) { -#ifdef WITH_SERIAL - if(console_service(&s) != 0) - s.run = false; -#endif -#ifdef WITH_ETH - ethernet_service(&s); -#endif - } - } - s.end = clock(); - - speed = (s.tick/2)/((s.end-s.start)/CLOCKS_PER_SEC); - - printf("average speed: %3.3f MHz\n\r", speed/1000000); - - tfp->close(); - - -#ifdef WITH_SERIAL_PTY - console_close(&s); -#endif -#ifdef WITH_ETH - eth_close(&s); -#endif - - exit(0); -} diff --git a/migen/build/sim/platform.py b/migen/build/sim/platform.py deleted file mode 100644 index 0c5e17d2..00000000 --- a/migen/build/sim/platform.py +++ /dev/null @@ -1,20 +0,0 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.sim import common, verilator - - -class SimPlatform(GenericPlatform): - def __init__(self, *args, toolchain="verilator", **kwargs): - GenericPlatform.__init__(self, *args, **kwargs) - if toolchain == "verilator": - self.toolchain = verilator.SimVerilatorToolchain() - else: - raise ValueError("Unknown toolchain") - - def get_verilog(self, *args, special_overrides=dict(), **kwargs): - so = dict(common.sim_special_overrides) - so.update(special_overrides) - return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs) - - def build(self, *args, **kwargs): - return self.toolchain.build(self, *args, **kwargs) - diff --git a/migen/build/sim/verilator.py b/migen/build/sim/verilator.py deleted file mode 100644 index 4e635528..00000000 --- a/migen/build/sim/verilator.py +++ /dev/null @@ -1,148 +0,0 @@ -# This file is Copyright (c) 2015 Florent Kermarrec -# License: BSD - -import os -import subprocess - -from migen.fhdl.structure import _Fragment -from migen.build import tools -from migen.build.generic_platform import * - - -def _build_tb(platform, vns, serial, template): - def io_name(resource, subsignal=None): - res = platform.lookup_request(resource) - if subsignal is not None: - res = getattr(res, subsignal) - return vns.get_name(res) - - ios = """ -#define SYS_CLK dut->{sys_clk} -""".format(sys_clk=io_name("sys_clk")) - - if serial == "pty": - ios += "#define WITH_SERIAL_PTY" - elif serial == "console": - pass - else: - raise ValueError - try: - ios += """ -#define SERIAL_SOURCE_STB dut->{serial_source_stb} -#define SERIAL_SOURCE_ACK dut->{serial_source_ack} -#define SERIAL_SOURCE_DATA dut->{serial_source_data} - -#define SERIAL_SINK_STB dut->{serial_sink_stb} -#define SERIAL_SINK_ACK dut->{serial_sink_ack} -#define SERIAL_SINK_DATA dut->{serial_sink_data} -""".format( - serial_source_stb=io_name("serial", "source_stb"), - serial_source_ack=io_name("serial", "source_ack"), - serial_source_data=io_name("serial", "source_data"), - - serial_sink_stb=io_name("serial", "sink_stb"), - serial_sink_ack=io_name("serial", "sink_ack"), - serial_sink_data=io_name("serial", "sink_data"), - ) - except: - pass - - try: - ios += """ -#define ETH_SOURCE_STB dut->{eth_source_stb} -#define ETH_SOURCE_ACK dut->{eth_source_ack} -#define ETH_SOURCE_DATA dut->{eth_source_data} - -#define ETH_SINK_STB dut->{eth_sink_stb} -#define ETH_SINK_ACK dut->{eth_sink_ack} -#define ETH_SINK_DATA dut->{eth_sink_data} -""".format( - eth_source_stb=io_name("eth", "source_stb"), - eth_source_ack=io_name("eth", "source_ack"), - eth_source_data=io_name("eth", "source_data"), - - eth_sink_stb=io_name("eth", "sink_stb"), - eth_sink_ack=io_name("eth", "sink_ack"), - eth_sink_data=io_name("eth", "sink_data"), - ) - except: - pass - - content = "" - f = open(template, "r") - done = False - for l in f: - content += l - if "/* ios */" in l and not done: - content += ios - done = True - - f.close() - tools.write_to_file("dut_tb.cpp", content) - - -def _build_sim(platform, vns, build_name, include_paths, sim_path, serial, verbose): - include = "" - for path in include_paths: - include += "-I"+path+" " - - build_script_contents = """# Autogenerated by Migen - rm -rf obj_dir/ -verilator {disable_warnings} -O3 --cc dut.v --exe dut_tb.cpp -LDFLAGS "-lpthread" -trace {include} -make -j -C obj_dir/ -f Vdut.mk Vdut - -""".format( - disable_warnings="-Wno-fatal", - include=include) - build_script_file = "build_" + build_name + ".sh" - tools.write_to_file(build_script_file, build_script_contents, force_unix=True) - - _build_tb(platform, vns, serial, os.path.join("..", sim_path, "dut_tb.cpp")) - if verbose: - r = subprocess.call(["bash", build_script_file]) - else: - r = subprocess.call(["bash", build_script_file], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) - if r != 0: - raise OSError("Subprocess failed") - - -def _run_sim(build_name): - run_script_contents = """obj_dir/Vdut -""" - run_script_file = "run_" + build_name + ".sh" - tools.write_to_file(run_script_file, run_script_contents, force_unix=True) - r = subprocess.call(["bash", run_script_file]) - if r != 0: - raise OSError("Subprocess failed") - - -class SimVerilatorToolchain: - # XXX fir sim_path - def build(self, platform, fragment, build_dir="build", build_name="top", - sim_path="../migen/migen/build/sim/", serial="console", - run=True, verbose=False): - tools.mkdir_noerror(build_dir) - os.chdir(build_dir) - - if not isinstance(fragment, _Fragment): - fragment = fragment.get_fragment() - platform.finalize(fragment) - - v_output = platform.get_verilog(fragment) - named_sc, named_pc = platform.resolve_signals(v_output.ns) - v_output.write("dut.v") - - include_paths = [] - for source in platform.sources: - path = os.path.dirname(source[0]).replace("\\", "\/") - if path not in include_paths: - include_paths.append(path) - include_paths += platform.verilog_include_paths - _build_sim(platform, v_output.ns, build_name, include_paths, sim_path, serial, verbose) - - if run: - _run_sim(build_name) - - os.chdir("..") - - return v_output.ns diff --git a/migen/build/tools.py b/migen/build/tools.py deleted file mode 100644 index 9e0880d5..00000000 --- a/migen/build/tools.py +++ /dev/null @@ -1,42 +0,0 @@ -import os -import struct -from distutils.version import StrictVersion - - -def mkdir_noerror(d): - try: - os.mkdir(d) - except OSError: - pass - - -def language_by_filename(name): - extension = name.rsplit(".")[-1] - if extension in ["v", "vh", "vo"]: - return "verilog" - if extension in ["vhd", "vhdl", "vho"]: - return "vhdl" - return None - - -def write_to_file(filename, contents, force_unix=False): - newline = None - if force_unix: - newline = "\n" - with open(filename, "w", newline=newline) as f: - f.write(contents) - - -def arch_bits(): - return struct.calcsize("P")*8 - - -def versions(path): - for n in os.listdir(path): - full = os.path.join(path, n) - if not os.path.isdir(full): - continue - try: - yield StrictVersion(n) - except ValueError: - continue diff --git a/migen/build/xilinx/__init__.py b/migen/build/xilinx/__init__.py deleted file mode 100644 index 4120abb8..00000000 --- a/migen/build/xilinx/__init__.py +++ /dev/null @@ -1,2 +0,0 @@ -from migen.build.xilinx.platform import XilinxPlatform -from migen.build.xilinx.programmer import UrJTAG, XC3SProg, FpgaProg, VivadoProgrammer, iMPACT, Adept diff --git a/migen/build/xilinx/common.py b/migen/build/xilinx/common.py deleted file mode 100644 index 52f8ca97..00000000 --- a/migen/build/xilinx/common.py +++ /dev/null @@ -1,150 +0,0 @@ -import os -import sys -from distutils.version import StrictVersion - -from migen.fhdl.structure import * -from migen.fhdl.specials import Instance -from migen.fhdl.module import Module -from migen.fhdl.specials import SynthesisDirective -from migen.genlib.cdc import * -from migen.genlib.resetsync import AsyncResetSynchronizer -from migen.genlib.io import * - -from migen.build import tools - - -def settings(path, ver=None, sub=None): - vers = list(tools.versions(path)) - if ver is None: - ver = max(vers) - else: - ver = StrictVersion(ver) - assert ver in vers - - full = os.path.join(path, str(ver)) - if sub: - full = os.path.join(full, sub) - - search = [64, 32] - if tools.arch_bits() == 32: - search.reverse() - - if sys.platform == "win32" or sys.platform == "cygwin": - script_ext = "bat" - else: - script_ext = "sh" - - for b in search: - settings = os.path.join(full, "settings{0}.{1}".format(b, script_ext)) - if os.path.exists(settings): - return settings - - raise OSError("no settings file found") - - -class XilinxNoRetimingImpl(Module): - def __init__(self, reg): - self.specials += SynthesisDirective("attribute register_balancing of {r} is no", r=reg) - - -class XilinxNoRetiming: - @staticmethod - def lower(dr): - return XilinxNoRetimingImpl(dr.reg) - - -class XilinxMultiRegImpl(MultiRegImpl): - def __init__(self, *args, **kwargs): - MultiRegImpl.__init__(self, *args, **kwargs) - self.specials += [SynthesisDirective("attribute shreg_extract of {r} is no", r=r) - for r in self.regs] - - -class XilinxMultiReg: - @staticmethod - def lower(dr): - return XilinxMultiRegImpl(dr.i, dr.o, dr.odomain, dr.n) - - -class XilinxAsyncResetSynchronizerImpl(Module): - def __init__(self, cd, async_reset): - rst1 = Signal() - self.specials += [ - Instance("FDPE", p_INIT=1, i_D=0, i_PRE=async_reset, - i_CE=1, i_C=cd.clk, o_Q=rst1), - Instance("FDPE", p_INIT=1, i_D=rst1, i_PRE=async_reset, - i_CE=1, i_C=cd.clk, o_Q=cd.rst) - ] - - -class XilinxAsyncResetSynchronizer: - @staticmethod - def lower(dr): - return XilinxAsyncResetSynchronizerImpl(dr.cd, dr.async_reset) - - -class XilinxDifferentialInputImpl(Module): - def __init__(self, i_p, i_n, o): - self.specials += Instance("IBUFDS", i_I=i_p, i_IB=i_n, o_O=o) - - -class XilinxDifferentialInput: - @staticmethod - def lower(dr): - return XilinxDifferentialInputImpl(dr.i_p, dr.i_n, dr.o) - - -class XilinxDifferentialOutputImpl(Module): - def __init__(self, i, o_p, o_n): - self.specials += Instance("OBUFDS", i_I=i, o_O=o_p, o_OB=o_n) - - -class XilinxDifferentialOutput: - @staticmethod - def lower(dr): - return XilinxDifferentialOutputImpl(dr.i, dr.o_p, dr.o_n) - - -class XilinxDDROutputImpl(Module): - def __init__(self, i1, i2, o, clk): - self.specials += Instance("ODDR2", - p_DDR_ALIGNMENT="NONE", p_INIT=0, p_SRTYPE="SYNC", - i_C0=clk, i_C1=~clk, i_CE=1, i_S=0, i_R=0, - i_D0=i1, i_D1=i2, o_Q=o, - ) - - -class XilinxDDROutput: - @staticmethod - def lower(dr): - return XilinxDDROutputImpl(dr.i1, dr.i2, dr.o, dr.clk) - - -xilinx_special_overrides = { - NoRetiming: XilinxNoRetiming, - MultiReg: XilinxMultiReg, - AsyncResetSynchronizer: XilinxAsyncResetSynchronizer, - DifferentialInput: XilinxDifferentialInput, - DifferentialOutput: XilinxDifferentialOutput, - DDROutput: XilinxDDROutput -} - - -class XilinxDDROutputImplS7(Module): - def __init__(self, i1, i2, o, clk): - self.specials += Instance("ODDR", - p_DDR_CLK_EDGE="SAME_EDGE", - i_C=clk, i_CE=1, i_S=0, i_R=0, - i_D1=i1, i_D2=i2, o_Q=o, - ) - - -class XilinxDDROutputS7: - @staticmethod - def lower(dr): - return XilinxDDROutputImplS7(dr.i1, dr.i2, dr.o, dr.clk) - - -xilinx_s7_special_overrides = { - DDROutput: XilinxDDROutputS7 -} diff --git a/migen/build/xilinx/ise.py b/migen/build/xilinx/ise.py deleted file mode 100644 index 72e82a90..00000000 --- a/migen/build/xilinx/ise.py +++ /dev/null @@ -1,198 +0,0 @@ -import os -import subprocess -import sys - -from migen.fhdl.structure import _Fragment -from migen.build.generic_platform import * -from migen.build import tools -from migen.build.xilinx import common - - -def _format_constraint(c): - if isinstance(c, Pins): - return "LOC=" + c.identifiers[0] - elif isinstance(c, IOStandard): - return "IOSTANDARD=" + c.name - elif isinstance(c, Drive): - return "DRIVE=" + str(c.strength) - elif isinstance(c, Misc): - return c.misc - - -def _format_ucf(signame, pin, others, resname): - fmt_c = [] - for c in [Pins(pin)] + others: - fc = _format_constraint(c) - if fc is not None: - fmt_c.append(fc) - fmt_r = resname[0] + ":" + str(resname[1]) - if resname[2] is not None: - fmt_r += "." + resname[2] - return "NET \"" + signame + "\" " + " | ".join(fmt_c) + "; # " + fmt_r + "\n" - - -def _build_ucf(named_sc, named_pc): - r = "" - for sig, pins, others, resname in named_sc: - if len(pins) > 1: - for i, p in enumerate(pins): - r += _format_ucf(sig + "(" + str(i) + ")", p, others, resname) - else: - r += _format_ucf(sig, pins[0], others, resname) - if named_pc: - r += "\n" + "\n\n".join(named_pc) - return r - - -def _build_xst_files(device, sources, vincpaths, build_name, xst_opt): - prj_contents = "" - for filename, language, library in sources: - prj_contents += language + " " + library + " " + filename + "\n" - tools.write_to_file(build_name + ".prj", prj_contents) - - xst_contents = """run --ifn {build_name}.prj --top top -{xst_opt} --ofn {build_name}.ngc --p {device} -""".format(build_name=build_name, xst_opt=xst_opt, device=device) - for path in vincpaths: - xst_contents += "-vlgincdir " + path + "\n" - tools.write_to_file(build_name + ".xst", xst_contents) - - -def _run_yosys(device, sources, vincpaths, build_name): - ys_contents = "" - incflags = "" - for path in vincpaths: - incflags += " -I" + path - for filename, language, library in sources: - ys_contents += "read_{}{} {}\n".format(language, incflags, filename) - - ys_contents += """hierarchy -check -top top -proc; memory; opt; fsm; opt -synth_xilinx -top top -edif {build_name}.edif""".format(build_name=build_name) - - ys_name = build_name + ".ys" - tools.write_to_file(ys_name, ys_contents) - r = subprocess.call(["yosys", ys_name]) - if r != 0: - raise OSError("Subprocess failed") - - -def _run_ise(build_name, ise_path, source, mode, ngdbuild_opt, - bitgen_opt, ise_commands, map_opt, par_opt, ver=None): - if sys.platform == "win32" or sys.platform == "cygwin": - source_cmd = "call " - script_ext = ".bat" - shell = ["cmd", "/c"] - build_script_contents = "@echo off\nrem Autogenerated by Migen\n" - else: - source_cmd = "source " - script_ext = ".sh" - shell = ["bash"] - build_script_contents = "# Autogenerated by Migen\nset -e\n" - if source: - settings = common.settings(ise_path, ver, "ISE_DS") - build_script_contents += source_cmd + settings + "\n" - if mode == "edif": - ext = "edif" - else: - ext = "ngc" - build_script_contents += """ -xst -ifn {build_name}.xst -""" - - build_script_contents += """ -ngdbuild {ngdbuild_opt} -uc {build_name}.ucf {build_name}.{ext} {build_name}.ngd -map {map_opt} -o {build_name}_map.ncd {build_name}.ngd {build_name}.pcf -par {par_opt} {build_name}_map.ncd {build_name}.ncd {build_name}.pcf -bitgen {bitgen_opt} {build_name}.ncd {build_name}.bit -""" - build_script_contents = build_script_contents.format(build_name=build_name, - ngdbuild_opt=ngdbuild_opt, bitgen_opt=bitgen_opt, ext=ext, - par_opt=par_opt, map_opt=map_opt) - build_script_contents += ise_commands.format(build_name=build_name) - build_script_file = "build_" + build_name + script_ext - tools.write_to_file(build_script_file, build_script_contents, force_unix=False) - command = shell + [build_script_file] - r = subprocess.call(command) - if r != 0: - raise OSError("Subprocess failed") - - -class XilinxISEToolchain: - def __init__(self): - self.xst_opt = """-ifmt MIXED --use_new_parser yes --opt_mode SPEED --register_balancing yes""" - self.map_opt = "-ol high -w" - self.par_opt = "-ol high -w" - self.ngdbuild_opt = "" - self.bitgen_opt = "-g Binary:Yes -w" - self.ise_commands = "" - - def build(self, platform, fragment, build_dir="build", build_name="top", - toolchain_path=None, source=None, run=True, mode="xst"): - if not isinstance(fragment, _Fragment): - fragment = fragment.get_fragment() - if toolchain_path is None: - if sys.platform == "win32": - toolchain_path = "C:\\Xilinx" - elif sys.platform == "cygwin": - toolchain_path = "/cygdrive/c/Xilinx" - else: - toolchain_path = "/opt/Xilinx" - if source is None: - source = sys.platform != "win32" - - platform.finalize(fragment) - ngdbuild_opt = self.ngdbuild_opt - vns = None - - tools.mkdir_noerror(build_dir) - cwd = os.getcwd() - os.chdir(build_dir) - try: - if mode == "xst" or mode == "yosys": - v_output = platform.get_verilog(fragment) - vns = v_output.ns - named_sc, named_pc = platform.resolve_signals(vns) - v_file = build_name + ".v" - v_output.write(v_file) - sources = platform.sources | {(v_file, "verilog", "work")} - if mode == "xst": - _build_xst_files(platform.device, sources, platform.verilog_include_paths, build_name, self.xst_opt) - isemode = "xst" - else: - _run_yosys(platform.device, sources, platform.verilog_include_paths, build_name) - isemode = "edif" - ngdbuild_opt += "-p " + platform.device - - if mode == "mist": - from mist import synthesize - synthesize(fragment, platform.constraint_manager.get_io_signals()) - - if mode == "edif" or mode == "mist": - e_output = platform.get_edif(fragment) - vns = e_output.ns - named_sc, named_pc = platform.resolve_signals(vns) - e_file = build_name + ".edif" - e_output.write(e_file) - isemode = "edif" - - tools.write_to_file(build_name + ".ucf", _build_ucf(named_sc, named_pc)) - if run: - _run_ise(build_name, toolchain_path, source, isemode, - ngdbuild_opt, self.bitgen_opt, self.ise_commands, - self.map_opt, self.par_opt) - finally: - os.chdir(cwd) - - return vns - - def add_period_constraint(self, platform, clk, period): - platform.add_platform_command("""NET "{clk}" TNM_NET = "GRP{clk}"; -TIMESPEC "TS{clk}" = PERIOD "GRP{clk}" """+str(period)+""" ns HIGH 50%;""", clk=clk) diff --git a/migen/build/xilinx/platform.py b/migen/build/xilinx/platform.py deleted file mode 100644 index d4ca4b18..00000000 --- a/migen/build/xilinx/platform.py +++ /dev/null @@ -1,33 +0,0 @@ -from migen.build.generic_platform import GenericPlatform -from migen.build.xilinx import common, vivado, ise - - -class XilinxPlatform(GenericPlatform): - bitstream_ext = ".bit" - - def __init__(self, *args, toolchain="ise", **kwargs): - GenericPlatform.__init__(self, *args, **kwargs) - if toolchain == "ise": - self.toolchain = ise.XilinxISEToolchain() - elif toolchain == "vivado": - self.toolchain = vivado.XilinxVivadoToolchain() - else: - raise ValueError("Unknown toolchain") - - def get_verilog(self, *args, special_overrides=dict(), **kwargs): - so = dict(common.xilinx_special_overrides) - if self.device[:3] == "xc7": - so.update(common.xilinx_s7_special_overrides) - so.update(special_overrides) - return GenericPlatform.get_verilog(self, *args, special_overrides=so, **kwargs) - - def get_edif(self, fragment, **kwargs): - return GenericPlatform.get_edif(self, fragment, "UNISIMS", "Xilinx", self.device, **kwargs) - - def build(self, *args, **kwargs): - return self.toolchain.build(self, *args, **kwargs) - - def add_period_constraint(self, clk, period): - if hasattr(clk, "p"): - clk = clk.p - self.toolchain.add_period_constraint(self, clk, period) diff --git a/migen/build/xilinx/programmer.py b/migen/build/xilinx/programmer.py deleted file mode 100644 index 8291465a..00000000 --- a/migen/build/xilinx/programmer.py +++ /dev/null @@ -1,201 +0,0 @@ -import os -import sys -import subprocess - -from migen.build.generic_programmer import GenericProgrammer -from migen.build.xilinx import common - - -def _run_urjtag(cmds): - with subprocess.Popen("jtag", stdin=subprocess.PIPE) as process: - process.stdin.write(cmds.encode("ASCII")) - process.communicate() - - -class UrJTAG(GenericProgrammer): - needs_bitreverse = True - - def __init__(self, cable, flash_proxy_basename=None): - GenericProgrammer.__init__(self, flash_proxy_basename) - self.cable = cable - - def load_bitstream(self, bitstream_file): - cmds = """cable {cable} -detect -pld load {bitstream} -quit -""".format(bitstream=bitstream_file, cable=self.cable) - _run_urjtag(cmds) - - def flash(self, address, data_file): - flash_proxy = self.find_flash_proxy() - cmds = """cable {cable} -detect -pld load "{flash_proxy}" -initbus fjmem opcode=000010 -frequency 6000000 -detectflash 0 -endian big -flashmem "{address}" "{data_file}" noverify -""".format(flash_proxy=flash_proxy, address=address, data_file=data_file, - cable=self.cable) - _run_urjtag(cmds) - - -class XC3SProg(GenericProgrammer): - needs_bitreverse = False - - def __init__(self, cable, flash_proxy_basename=None): - GenericProgrammer.__init__(self, flash_proxy_basename) - self.cable = cable - - def load_bitstream(self, bitstream_file): - subprocess.call(["xc3sprog", "-v", "-c", self.cable, bitstream_file]) - - def flash(self, address, data_file): - flash_proxy = self.find_flash_proxy() - subprocess.call(["xc3sprog", "-v", "-c", self.cable, "-I"+flash_proxy, "{}:w:0x{:x}:BIN".format(data_file, address)]) - - - -class FpgaProg(GenericProgrammer): - needs_bitreverse = False - - def __init__(self, flash_proxy_basename=None): - GenericProgrammer.__init__(self, flash_proxy_basename) - - def load_bitstream(self, bitstream_file): - subprocess.call(["fpgaprog", "-v", "-f", bitstream_file]) - - def flash(self, address, data_file): - if address != 0: - raise ValueError("fpga prog needs a main bitstream at address 0") - flash_proxy = self.find_flash_proxy() - subprocess.call(["fpgaprog", "-v", "-sa", "-r", "-b", flash_proxy, - "-f", data_file]) - - -def _run_impact(cmds): - with subprocess.Popen("impact -batch", stdin=subprocess.PIPE, shell=True) as process: - process.stdin.write(cmds.encode("ASCII")) - process.communicate() - return process.returncode - - -def _create_xsvf(bitstream_file, xsvf_file): - assert os.path.exists(bitstream_file), bitstream_file - assert not os.path.exists(xsvf_file), xsvf_file - assert 0 == _run_impact(""" -setPreference -pref KeepSVF:True -setMode -bs -setCable -port xsvf -file {xsvf} -addDevice -p 1 -file {bitstream} -program -p 1 -quit -""".format(bitstream=bitstream_file, xsvf=xsvf_file)) - - -class iMPACT(GenericProgrammer): - needs_bitreverse = False - - def load_bitstream(self, bitstream_file): - cmds = """setMode -bs -setCable -p auto -addDevice -p 1 -file {bitstream} -program -p 1 -quit -""".format(bitstream=bitstream_file) - _run_impact(cmds) - - -def _run_vivado(path, ver, cmds): - if sys.platform == "win32" or sys.platform == "cygwin": - vivado_cmd = "vivado -mode tcl" - else: - settings = common.settings(path, ver) - vivado_cmd = "bash -c \"source " + settings + "&& vivado -mode tcl\"" - with subprocess.Popen(vivado_cmd, stdin=subprocess.PIPE, shell=True) as process: - process.stdin.write(cmds.encode("ASCII")) - process.communicate() - - -class VivadoProgrammer(GenericProgrammer): - needs_bitreverse = False - def __init__(self, vivado_path="/opt/Xilinx/Vivado", vivado_ver=None, - flash_part="n25q256-3.3v-spi-x1_x2_x4"): - GenericProgrammer.__init__(self) - self.vivado_path = vivado_path - self.vivado_ver = vivado_ver - self.flash_part = flash_part - - def load_bitstream(self, bitstream_file): - cmds = """open_hw -connect_hw_server -open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0] - -set_property PROBES.FILE {{}} [lindex [get_hw_devices] 0] -set_property PROGRAM.FILE {{{bitstream}}} [lindex [get_hw_devices] 0] - -program_hw_devices [lindex [get_hw_devices] 0] -refresh_hw_device [lindex [get_hw_devices] 0] - -quit -""".format(bitstream=bitstream_file) - _run_vivado(self.vivado_path, self.vivado_ver, cmds) - - # XXX works to flash bitstream, adapt it to flash bios - def flash(self, address, data_file): - cmds = """open_hw -connect_hw_server -open_hw_target [lindex [get_hw_targets -of_objects [get_hw_servers localhost]] 0] -create_hw_cfgmem -hw_device [lindex [get_hw_devices] 0] -mem_dev [lindex [get_cfgmem_parts {{{flash_part}}}] 0] - -set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -refresh_hw_device [lindex [get_hw_devices] 0] - -set_property PROGRAM.ADDRESS_RANGE {{use_file}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.FILES [list "{data}" ] [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0]] -set_property PROGRAM.UNUSED_PIN_TERMINATION {{pull-none}} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] - -startgroup -if {{![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]]]]] }} {{ create_hw_bitstream -hw_device [lindex [get_hw_devices] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices] 0]]; program_hw_devices [lindex [get_hw_devices] 0]; }}; -program_hw_cfgmem -hw_cfgmem [get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices] 0 ]] -endgroup - -quit -""".format(data=data_file, flash_part=self.flash_part) - _run_vivado(self.vivado_path, self.vivado_ver, cmds) - - -class Adept(GenericProgrammer): - """Using the Adept tool with an onboard Digilent "USB JTAG" cable. - - You need to install Adept Utilities V2 from - http://www.digilentinc.com/Products/Detail.cfm?NavPath=2,66,828&Prod=ADEPT2 - """ - - needs_bitreverse = False - - def __init__(self, board, index, flash_proxy_basename=None): - GenericProgrammer.__init__(self, flash_proxy_basename) - self.board = board - self.index = index - - def load_bitstream(self, bitstream_file): - subprocess.call([ - "djtgcfg", - "--verbose", - "prog", "-d", self.board, - "-i", str(self.index), - "-f", bitstream_file, - ]) - - def flash(self, address, data_file): - raise ValueError("Flashing unsupported with DigilentAdept tools") diff --git a/migen/fhdl/__init__.py b/migen/fhdl/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/migen/fhdl/conv_output.py b/migen/fhdl/conv_output.py deleted file mode 100644 index 793fad20..00000000 --- a/migen/fhdl/conv_output.py +++ /dev/null @@ -1,35 +0,0 @@ -from operator import itemgetter - - -class ConvOutput: - def __init__(self): - self.main_source = "" - self.data_files = dict() - - def set_main_source(self, src): - self.main_source = src - - def add_data_file(self, filename_base, content): - filename = filename_base - i = 1 - while filename in self.data_files: - parts = filename_base.split(".", maxsplit=1) - parts[0] += "_" + str(i) - filename = ".".join(parts) - i += 1 - self.data_files[filename] = content - return filename - - def __str__(self): - r = self.main_source + "\n" - for filename, content in sorted(self.data_files.items(), - key=itemgetter(0)): - r += filename + ":\n" + content - return r - - def write(self, main_filename): - with open(main_filename, "w") as f: - f.write(self.main_source) - for filename, content in self.data_files.items(): - with open(filename, "w") as f: - f.write(content) diff --git a/migen/fhdl/decorators.py b/migen/fhdl/decorators.py deleted file mode 100644 index 694479c5..00000000 --- a/migen/fhdl/decorators.py +++ /dev/null @@ -1,107 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.tools import insert_reset, rename_clock_domain - - -__all__ = ["CEInserter", "ResetInserter", "ClockDomainsRenamer", - "ModuleTransformer"] - - -class ModuleTransformer: - # overload this in derived classes - def transform_instance(self, i): - pass - - # overload this in derived classes - def transform_fragment(self, i, f): - pass - - def wrap_class(self, victim): - class Wrapped(victim): - def __init__(i, *args, **kwargs): - victim.__init__(i, *args, **kwargs) - self.transform_instance(i) - - def get_fragment(i): - f = victim.get_fragment(i) - self.transform_fragment(i, f) - return f - - Wrapped.__name__ = victim.__name__ - # "{}_{}".format(self.__class__.__name__, victim.__name__) - return Wrapped - - def wrap_instance(self, victim): - self.transform_instance(victim) - orig_get_fragment = victim.get_fragment - - def get_fragment(): - f = orig_get_fragment() - self.transform_fragment(victim, f) - return f - - victim.get_fragment = get_fragment - return victim - - def __call__(self, victim): - if isinstance(victim, Module): - return self.wrap_instance(victim) - else: - return self.wrap_class(victim) - - -class ControlInserter(ModuleTransformer): - control_name = None # override this - - def __init__(self, clock_domains=None): - self.clock_domains = clock_domains - - def transform_instance(self, i): - if self.clock_domains is None: - ctl = Signal(name=self.control_name) - assert not hasattr(i, self.control_name) - setattr(i, self.control_name, ctl) - else: - for cd in self.clock_domains: - name = self.control_name + "_" + cd - ctl = Signal(name=name) - assert not hasattr(i, name) - setattr(i, name, ctl) - - def transform_fragment(self, i, f): - if self.clock_domains is None: - if len(f.sync) != 1: - raise ValueError("Control signal clock domains must be specified when module has more than one domain") - cdn = list(f.sync.keys())[0] - to_insert = [(getattr(i, self.control_name), cdn)] - else: - to_insert = [(getattr(i, self.control_name + "_" + cdn), cdn) - for cdn in self.clock_domains] - self.transform_fragment_insert(i, f, to_insert) - - -class CEInserter(ControlInserter): - control_name = "ce" - - def transform_fragment_insert(self, i, f, to_insert): - for ce, cdn in to_insert: - f.sync[cdn] = [If(ce, *f.sync[cdn])] - - -class ResetInserter(ControlInserter): - control_name = "reset" - - def transform_fragment_insert(self, i, f, to_insert): - for reset, cdn in to_insert: - f.sync[cdn] = insert_reset(reset, f.sync[cdn]) - - -class ClockDomainsRenamer(ModuleTransformer): - def __init__(self, cd_remapping): - if isinstance(cd_remapping, str): - cd_remapping = {"sys": cd_remapping} - self.cd_remapping = cd_remapping - - def transform_fragment(self, i, f): - for old, new in self.cd_remapping.items(): - rename_clock_domain(f, old, new) diff --git a/migen/fhdl/namer.py b/migen/fhdl/namer.py deleted file mode 100644 index 8e0f450d..00000000 --- a/migen/fhdl/namer.py +++ /dev/null @@ -1,258 +0,0 @@ -from collections import OrderedDict -from itertools import combinations - -from migen.fhdl.structure import * - - -class _Node: - def __init__(self): - self.signal_count = 0 - self.numbers = set() - self.use_name = False - self.use_number = False - self.children = OrderedDict() - - -def _display_tree(filename, tree): - from migen.util.treeviz import RenderNode - - def _to_render_node(name, node): - children = [_to_render_node(k, v) for k, v in node.children.items()] - if node.use_name: - if node.use_number: - color = (0.5, 0.9, 0.8) - else: - color = (0.8, 0.5, 0.9) - else: - if node.use_number: - color = (0.9, 0.8, 0.5) - else: - color = (0.8, 0.8, 0.8) - label = "{0}\n{1} signals\n{2}".format(name, node.signal_count, node.numbers) - return RenderNode(label, children, color=color) - - top = _to_render_node("top", tree) - top.to_svg(filename) - - -def _build_tree(signals, basic_tree=None): - root = _Node() - for signal in signals: - current_b = basic_tree - current = root - current.signal_count += 1 - for name, number in signal.backtrace: - if basic_tree is None: - use_number = False - else: - current_b = current_b.children[name] - use_number = current_b.use_number - if use_number: - key = (name, number) - else: - key = name - try: - current = current.children[key] - except KeyError: - new = _Node() - current.children[key] = new - current = new - current.numbers.add(number) - if use_number: - current.all_numbers = sorted(current_b.numbers) - current.signal_count += 1 - return root - - -def _set_use_name(node, node_name=""): - cnames = [(k, _set_use_name(v, k)) for k, v in node.children.items()] - for (c1_prefix, c1_names), (c2_prefix, c2_names) in combinations(cnames, 2): - if not c1_names.isdisjoint(c2_names): - node.children[c1_prefix].use_name = True - node.children[c2_prefix].use_name = True - r = set() - for c_prefix, c_names in cnames: - if node.children[c_prefix].use_name: - for c_name in c_names: - r.add((c_prefix, ) + c_name) - else: - r |= c_names - - if node.signal_count > sum(c.signal_count for c in node.children.values()): - node.use_name = True - r.add((node_name, )) - - return r - - -def _name_signal(tree, signal): - elements = [] - treepos = tree - for step_name, step_n in signal.backtrace: - try: - treepos = treepos.children[(step_name, step_n)] - use_number = True - except KeyError: - treepos = treepos.children[step_name] - use_number = False - if treepos.use_name: - elname = step_name - if use_number: - elname += str(treepos.all_numbers.index(step_n)) - elements.append(elname) - return "_".join(elements) - - -def _build_pnd_from_tree(tree, signals): - return dict((signal, _name_signal(tree, signal)) for signal in signals) - - -def _invert_pnd(pnd): - inv_pnd = dict() - for k, v in pnd.items(): - inv_pnd[v] = inv_pnd.get(v, []) - inv_pnd[v].append(k) - return inv_pnd - - -def _list_conflicting_signals(pnd): - inv_pnd = _invert_pnd(pnd) - r = set() - for k, v in inv_pnd.items(): - if len(v) > 1: - r.update(v) - return r - - -def _set_use_number(tree, signals): - for signal in signals: - current = tree - for step_name, step_n in signal.backtrace: - current = current.children[step_name] - current.use_number = current.signal_count > len(current.numbers) and len(current.numbers) > 1 - -_debug = False - - -def _build_pnd_for_group(group_n, signals): - basic_tree = _build_tree(signals) - _set_use_name(basic_tree) - if _debug: - _display_tree("tree{0}_basic.svg".format(group_n), basic_tree) - pnd = _build_pnd_from_tree(basic_tree, signals) - - # If there are conflicts, try splitting the tree by numbers - # on paths taken by conflicting signals. - conflicting_signals = _list_conflicting_signals(pnd) - if conflicting_signals: - _set_use_number(basic_tree, conflicting_signals) - if _debug: - print("namer: using split-by-number strategy (group {0})".format(group_n)) - _display_tree("tree{0}_marked.svg".format(group_n), basic_tree) - numbered_tree = _build_tree(signals, basic_tree) - _set_use_name(numbered_tree) - if _debug: - _display_tree("tree{0}_numbered.svg".format(group_n), numbered_tree) - pnd = _build_pnd_from_tree(numbered_tree, signals) - else: - if _debug: - print("namer: using basic strategy (group {0})".format(group_n)) - - # ...then add number suffixes by DUID - inv_pnd = _invert_pnd(pnd) - duid_suffixed = False - for name, signals in inv_pnd.items(): - if len(signals) > 1: - duid_suffixed = True - for n, signal in enumerate(sorted(signals, key=lambda x: x.duid)): - pnd[signal] += str(n) - if _debug and duid_suffixed: - print("namer: using DUID suffixes (group {0})".format(group_n)) - - return pnd - - -def _build_signal_groups(signals): - r = [] - for signal in signals: - # build chain of related signals - related_list = [] - cur_signal = signal - while cur_signal is not None: - related_list.insert(0, cur_signal) - cur_signal = cur_signal.related - # add to groups - for _ in range(len(related_list) - len(r)): - r.append(set()) - for target_set, source_signal in zip(r, related_list): - target_set.add(source_signal) - # with the algorithm above and a list of all signals, - # a signal appears in all groups of a lower number than its. - # make signals appear only in their group of highest number. - for s1, s2 in zip(r, r[1:]): - s1 -= s2 - return r - - -def _build_pnd(signals): - groups = _build_signal_groups(signals) - gpnds = [_build_pnd_for_group(n, gsignals) for n, gsignals in enumerate(groups)] - - pnd = dict() - for gn, gpnd in enumerate(gpnds): - for signal, name in gpnd.items(): - result = name - cur_gn = gn - cur_signal = signal - while cur_signal.related is not None: - cur_signal = cur_signal.related - cur_gn -= 1 - result = gpnds[cur_gn][cur_signal] + "_" + result - pnd[signal] = result - - return pnd - - -def build_namespace(signals, reserved_keywords=set()): - pnd = _build_pnd(signals) - ns = Namespace(pnd, reserved_keywords) - # register signals with name_override - for signal in signals: - if signal.name_override is not None: - ns.get_name(signal) - return ns - - -class Namespace: - def __init__(self, pnd, reserved_keywords=set()): - self.counts = {k: 1 for k in reserved_keywords} - self.sigs = {} - self.pnd = pnd - self.clock_domains = dict() - - def get_name(self, sig): - if isinstance(sig, ClockSignal): - sig = self.clock_domains[sig.cd].clk - if isinstance(sig, ResetSignal): - sig = self.clock_domains[sig.cd].rst - if sig is None: - raise ValueError("Attempted to obtain name of non-existent " - "reset signal of domain "+sig.cd) - - if sig.name_override is not None: - sig_name = sig.name_override - else: - sig_name = self.pnd[sig] - try: - n = self.sigs[sig] - except KeyError: - try: - n = self.counts[sig_name] - except KeyError: - n = 0 - self.sigs[sig] = n - self.counts[sig_name] = n + 1 - if n: - return sig_name + "_" + str(n) - else: - return sig_name diff --git a/migen/fhdl/tools.py b/migen/fhdl/tools.py deleted file mode 100644 index ddc135c2..00000000 --- a/migen/fhdl/tools.py +++ /dev/null @@ -1,298 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.structure import _Slice, _Assign -from migen.fhdl.visit import NodeVisitor, NodeTransformer -from migen.fhdl.bitcontainer import value_bits_sign -from migen.util.misc import flat_iteration - - -class _SignalLister(NodeVisitor): - def __init__(self): - self.output_list = set() - - def visit_Signal(self, node): - self.output_list.add(node) - - -class _TargetLister(NodeVisitor): - def __init__(self): - self.output_list = set() - self.target_context = False - - def visit_Signal(self, node): - if self.target_context: - self.output_list.add(node) - - def visit_Assign(self, node): - self.target_context = True - self.visit(node.l) - self.target_context = False - - def visit_ArrayProxy(self, node): - for choice in node.choices: - self.visit(choice) - - -class _InputLister(NodeVisitor): - def __init__(self): - self.output_list = set() - - def visit_Signal(self, node): - self.output_list.add(node) - - def visit_Assign(self, node): - self.visit(node.r) - - -def list_signals(node): - lister = _SignalLister() - lister.visit(node) - return lister.output_list - - -def list_targets(node): - lister = _TargetLister() - lister.visit(node) - return lister.output_list - - -def list_inputs(node): - lister = _InputLister() - lister.visit(node) - return lister.output_list - - -def _resort_statements(ol): - return [statement for i, statement in - sorted(ol, key=lambda x: x[0])] - - -def group_by_targets(sl): - groups = [] - seen = set() - for order, stmt in enumerate(flat_iteration(sl)): - targets = set(list_targets(stmt)) - group = [(order, stmt)] - disjoint = targets.isdisjoint(seen) - seen |= targets - if not disjoint: - groups, old_groups = [], groups - for old_targets, old_group in old_groups: - if targets.isdisjoint(old_targets): - groups.append((old_targets, old_group)) - else: - targets |= old_targets - group += old_group - groups.append((targets, group)) - return [(targets, _resort_statements(stmts)) - for targets, stmts in groups] - - -def list_special_ios(f, ins, outs, inouts): - r = set() - for special in f.specials: - r |= special.list_ios(ins, outs, inouts) - return r - - -class _ClockDomainLister(NodeVisitor): - def __init__(self): - self.clock_domains = set() - - def visit_ClockSignal(self, node): - self.clock_domains.add(node.cd) - - def visit_ResetSignal(self, node): - self.clock_domains.add(node.cd) - - def visit_clock_domains(self, node): - for clockname, statements in node.items(): - self.clock_domains.add(clockname) - self.visit(statements) - - -def list_clock_domains_expr(f): - cdl = _ClockDomainLister() - cdl.visit(f) - return cdl.clock_domains - - -def list_clock_domains(f): - r = list_clock_domains_expr(f) - for special in f.specials: - r |= special.list_clock_domains() - for cd in f.clock_domains: - r.add(cd.name) - return r - - -def is_variable(node): - if isinstance(node, Signal): - return node.variable - elif isinstance(node, _Slice): - return is_variable(node.value) - elif isinstance(node, Cat): - arevars = list(map(is_variable, node.l)) - r = arevars[0] - for x in arevars: - if x != r: - raise TypeError - return r - else: - raise TypeError - - -def generate_reset(rst, sl): - targets = list_targets(sl) - return [t.eq(t.reset) for t in sorted(targets, key=lambda x: x.duid)] - - -def insert_reset(rst, sl): - return [If(rst, *generate_reset(rst, sl)).Else(*sl)] - - -def insert_resets(f): - newsync = dict() - for k, v in f.sync.items(): - if f.clock_domains[k].rst is not None: - newsync[k] = insert_reset(ResetSignal(k), v) - else: - newsync[k] = v - f.sync = newsync - - -class _Lowerer(NodeTransformer): - def __init__(self): - self.target_context = False - self.extra_stmts = [] - self.comb = [] - - def visit_Assign(self, node): - old_target_context, old_extra_stmts = self.target_context, self.extra_stmts - self.extra_stmts = [] - - self.target_context = True - lhs = self.visit(node.l) - self.target_context = False - rhs = self.visit(node.r) - r = _Assign(lhs, rhs) - if self.extra_stmts: - r = [r] + self.extra_stmts - - self.target_context, self.extra_stmts = old_target_context, old_extra_stmts - return r - - -# Basics are FHDL structure elements that back-ends are not required to support -# but can be expressed in terms of other elements (lowered) before conversion. -class _BasicLowerer(_Lowerer): - def __init__(self, clock_domains): - self.clock_domains = clock_domains - _Lowerer.__init__(self) - - def visit_ArrayProxy(self, node): - # TODO: rewrite without variables - array_muxed = Signal(value_bits_sign(node), variable=True) - if self.target_context: - k = self.visit(node.key) - cases = {} - for n, choice in enumerate(node.choices): - cases[n] = [self.visit_Assign(_Assign(choice, array_muxed))] - self.extra_stmts.append(Case(k, cases).makedefault()) - else: - cases = dict((n, _Assign(array_muxed, self.visit(choice))) - for n, choice in enumerate(node.choices)) - self.comb.append(Case(self.visit(node.key), cases).makedefault()) - return array_muxed - - def visit_ClockSignal(self, node): - return self.clock_domains[node.cd].clk - - def visit_ResetSignal(self, node): - rst = self.clock_domains[node.cd].rst - if rst is None: - if node.allow_reset_less: - return 0 - else: - raise ValueError("Attempted to get reset signal of resetless" - " domain '{}'".format(node.cd)) - else: - return rst - - -class _ComplexSliceLowerer(_Lowerer): - def visit_Slice(self, node): - if not isinstance(node.value, Signal): - slice_proxy = Signal(value_bits_sign(node.value)) - if self.target_context: - a = _Assign(node.value, slice_proxy) - else: - a = _Assign(slice_proxy, node.value) - self.comb.append(self.visit_Assign(a)) - node = _Slice(slice_proxy, node.start, node.stop) - return NodeTransformer.visit_Slice(self, node) - - -def _apply_lowerer(l, f): - f = l.visit(f) - f.comb += l.comb - - for special in f.specials: - for obj, attr, direction in special.iter_expressions(): - if direction != SPECIAL_INOUT: - # inouts are only supported by Migen when connected directly to top-level - # in this case, they are Signal and never need lowering - l.comb = [] - l.target_context = direction != SPECIAL_INPUT - l.extra_stmts = [] - expr = getattr(obj, attr) - expr = l.visit(expr) - setattr(obj, attr, expr) - f.comb += l.comb + l.extra_stmts - - return f - - -def lower_basics(f): - return _apply_lowerer(_BasicLowerer(f.clock_domains), f) - - -def lower_complex_slices(f): - return _apply_lowerer(_ComplexSliceLowerer(), f) - - -class _ClockDomainRenamer(NodeVisitor): - def __init__(self, old, new): - self.old = old - self.new = new - - def visit_ClockSignal(self, node): - if node.cd == self.old: - node.cd = self.new - - def visit_ResetSignal(self, node): - if node.cd == self.old: - node.cd = self.new - - -def rename_clock_domain_expr(f, old, new): - cdr = _ClockDomainRenamer(old, new) - cdr.visit(f) - - -def rename_clock_domain(f, old, new): - rename_clock_domain_expr(f, old, new) - if new != old: - if old in f.sync: - if new in f.sync: - f.sync[new].extend(f.sync[old]) - else: - f.sync[new] = f.sync[old] - del f.sync[old] - for special in f.specials: - special.rename_clock_domain(old, new) - try: - cd = f.clock_domains[old] - except KeyError: - pass - else: - cd.rename(new) diff --git a/migen/fhdl/tracer.py b/migen/fhdl/tracer.py deleted file mode 100644 index a394f93f..00000000 --- a/migen/fhdl/tracer.py +++ /dev/null @@ -1,115 +0,0 @@ -import inspect -from opcode import opname -from collections import defaultdict - - -def get_var_name(frame): - code = frame.f_code - call_index = frame.f_lasti - call_opc = opname[code.co_code[call_index]] - if call_opc != "CALL_FUNCTION" and call_opc != "CALL_FUNCTION_VAR": - return None - index = call_index+3 - while True: - opc = opname[code.co_code[index]] - if opc == "STORE_NAME" or opc == "STORE_ATTR": - name_index = int(code.co_code[index+1]) - return code.co_names[name_index] - elif opc == "STORE_FAST": - name_index = int(code.co_code[index+1]) - return code.co_varnames[name_index] - elif opc == "STORE_DEREF": - name_index = int(code.co_code[index+1]) - return code.co_cellvars[name_index] - elif opc == "LOAD_GLOBAL" or opc == "LOAD_ATTR" or opc == "LOAD_FAST" or opc == "LOAD_DEREF": - index += 3 - elif opc == "DUP_TOP": - index += 1 - elif opc == "BUILD_LIST": - index += 3 - else: - return None - - -def remove_underscore(s): - if len(s) > 2 and s[0] == "_" and s[1] != "_": - s = s[1:] - return s - - -def get_obj_var_name(override=None, default=None): - if override: - return override - - frame = inspect.currentframe().f_back - # We can be called via derived classes. Go back the stack frames - # until we reach the first class that does not inherit from us. - ourclass = frame.f_locals["self"].__class__ - while "self" in frame.f_locals and isinstance(frame.f_locals["self"], ourclass): - frame = frame.f_back - - vn = get_var_name(frame) - if vn is None: - vn = default - else: - vn = remove_underscore(vn) - return vn - -name_to_idx = defaultdict(int) -classname_to_objs = dict() - - -def index_id(l, obj): - for n, e in enumerate(l): - if id(e) == id(obj): - return n - raise ValueError - - -def trace_back(varname=None): - l = [] - frame = inspect.currentframe().f_back.f_back - while frame is not None: - if varname is None: - varname = get_var_name(frame) - if varname is not None: - varname = remove_underscore(varname) - l.insert(0, (varname, name_to_idx[varname])) - name_to_idx[varname] += 1 - - try: - obj = frame.f_locals["self"] - except KeyError: - obj = None - if hasattr(obj, "__del__"): - obj = None - - if obj is None: - if varname is not None: - coname = frame.f_code.co_name - if coname == "": - modules = frame.f_globals["__name__"] - modules = modules.split(".") - coname = modules[len(modules)-1] - coname = remove_underscore(coname) - l.insert(0, (coname, name_to_idx[coname])) - name_to_idx[coname] += 1 - else: - classname = obj.__class__.__name__.lower() - try: - objs = classname_to_objs[classname] - except KeyError: - classname_to_objs[classname] = [obj] - idx = 0 - else: - try: - idx = index_id(objs, obj) - except ValueError: - idx = len(objs) - objs.append(obj) - classname = remove_underscore(classname) - l.insert(0, (classname, idx)) - - varname = None - frame = frame.f_back - return l diff --git a/migen/fhdl/verilog.py b/migen/fhdl/verilog.py deleted file mode 100644 index 19bba1fa..00000000 --- a/migen/fhdl/verilog.py +++ /dev/null @@ -1,361 +0,0 @@ -from functools import partial -from operator import itemgetter -import collections - -from migen.fhdl.structure import * -from migen.fhdl.structure import _Operator, _Slice, _Assign, _Fragment -from migen.fhdl.tools import * -from migen.fhdl.bitcontainer import bits_for -from migen.fhdl.namer import build_namespace -from migen.fhdl.conv_output import ConvOutput - - -_reserved_keywords = { - "always", "and", "assign", "automatic", "begin", "buf", "bufif0", "bufif1", - "case", "casex", "casez", "cell", "cmos", "config", "deassign", "default", - "defparam", "design", "disable", "edge", "else", "end", "endcase", - "endconfig", "endfunction", "endgenerate", "endmodule", "endprimitive", - "endspecify", "endtable", "endtask", "event", "for", "force", "forever", - "fork", "function", "generate", "genvar", "highz0", "highz1", "if", - "ifnone", "incdir", "include", "initial", "inout", "input", - "instance", "integer", "join", "large", "liblist", "library", "localparam", - "macromodule", "medium", "module", "nand", "negedge", "nmos", "nor", - "noshowcancelled", "not", "notif0", "notif1", "or", "output", "parameter", - "pmos", "posedge", "primitive", "pull0", "pull1" "pulldown", - "pullup", "pulsestyle_onevent", "pulsestyle_ondetect", "remos", "real", - "realtime", "reg", "release", "repeat", "rnmos", "rpmos", "rtran", - "rtranif0", "rtranif1", "scalared", "showcancelled", "signed", "small", - "specify", "specparam", "strong0", "strong1", "supply0", "supply1", - "table", "task", "time", "tran", "tranif0", "tranif1", "tri", "tri0", - "tri1", "triand", "trior", "trireg", "unsigned", "use", "vectored", "wait", - "wand", "weak0", "weak1", "while", "wire", "wor","xnor", "xor" -} - - -def _printsig(ns, s): - if s.signed: - n = "signed " - else: - n = "" - if len(s) > 1: - n += "[" + str(len(s)-1) + ":0] " - n += ns.get_name(s) - return n - - -def _printconstant(node): - if node.signed: - return (str(node.nbits) + "'sd" + str(2**node.nbits + node.value), - True) - else: - return str(node.nbits) + "'d" + str(node.value), False - - -def _printexpr(ns, node): - if isinstance(node, Constant): - return _printconstant(node) - elif isinstance(node, Signal): - return ns.get_name(node), node.signed - elif isinstance(node, _Operator): - arity = len(node.operands) - r1, s1 = _printexpr(ns, node.operands[0]) - if arity == 1: - if node.op == "-": - if s1: - r = node.op + r1 - else: - r = "-$signed({1'd0, " + r1 + "})" - s = True - else: - r = node.op + r1 - s = s1 - elif arity == 2: - r2, s2 = _printexpr(ns, node.operands[1]) - if node.op not in ["<<<", ">>>"]: - if s2 and not s1: - r1 = "$signed({1'd0, " + r1 + "})" - if s1 and not s2: - r2 = "$signed({1'd0, " + r2 + "})" - r = r1 + " " + node.op + " " + r2 - s = s1 or s2 - elif arity == 3: - assert node.op == "m" - r2, s2 = _printexpr(ns, node.operands[1]) - r3, s3 = _printexpr(ns, node.operands[2]) - if s2 and not s3: - r3 = "$signed({1'd0, " + r3 + "})" - if s3 and not s2: - r2 = "$signed({1'd0, " + r2 + "})" - r = r1 + " ? " + r2 + " : " + r3 - s = s2 or s3 - else: - raise TypeError - return "(" + r + ")", s - elif isinstance(node, _Slice): - # Verilog does not like us slicing non-array signals... - if isinstance(node.value, Signal) \ - and len(node.value) == 1 \ - and node.start == 0 and node.stop == 1: - return _printexpr(ns, node.value) - - if node.start + 1 == node.stop: - sr = "[" + str(node.start) + "]" - else: - sr = "[" + str(node.stop-1) + ":" + str(node.start) + "]" - r, s = _printexpr(ns, node.value) - return r + sr, s - elif isinstance(node, Cat): - l = [_printexpr(ns, v)[0] for v in reversed(node.l)] - return "{" + ", ".join(l) + "}", False - elif isinstance(node, Replicate): - return "{" + str(node.n) + "{" + _printexpr(ns, node.v)[0] + "}}", False - else: - raise TypeError("Expression of unrecognized type: '{}'".format(type(node).__name__)) - - -(_AT_BLOCKING, _AT_NONBLOCKING, _AT_SIGNAL) = range(3) - - -def _printnode(ns, at, level, node): - if node is None: - return "" - elif isinstance(node, _Assign): - if at == _AT_BLOCKING: - assignment = " = " - elif at == _AT_NONBLOCKING: - assignment = " <= " - elif is_variable(node.l): - assignment = " = " - else: - assignment = " <= " - return "\t"*level + _printexpr(ns, node.l)[0] + assignment + _printexpr(ns, node.r)[0] + ";\n" - elif isinstance(node, collections.Iterable): - return "".join(list(map(partial(_printnode, ns, at, level), node))) - elif isinstance(node, If): - r = "\t"*level + "if (" + _printexpr(ns, node.cond)[0] + ") begin\n" - r += _printnode(ns, at, level + 1, node.t) - if node.f: - r += "\t"*level + "end else begin\n" - r += _printnode(ns, at, level + 1, node.f) - r += "\t"*level + "end\n" - return r - elif isinstance(node, Case): - if node.cases: - r = "\t"*level + "case (" + _printexpr(ns, node.test)[0] + ")\n" - css = [(k, v) for k, v in node.cases.items() if isinstance(k, Constant)] - css = sorted(css, key=lambda x: x[0].value) - for choice, statements in css: - r += "\t"*(level + 1) + _printexpr(ns, choice)[0] + ": begin\n" - r += _printnode(ns, at, level + 2, statements) - r += "\t"*(level + 1) + "end\n" - if "default" in node.cases: - r += "\t"*(level + 1) + "default: begin\n" - r += _printnode(ns, at, level + 2, node.cases["default"]) - r += "\t"*(level + 1) + "end\n" - r += "\t"*level + "endcase\n" - return r - else: - return "" - else: - raise TypeError("Node of unrecognized type: "+str(type(node))) - - -def _list_comb_wires(f): - r = set() - groups = group_by_targets(f.comb) - for g in groups: - if len(g[1]) == 1 and isinstance(g[1][0], _Assign): - r |= g[0] - return r - - -def _printheader(f, ios, name, ns, - reg_initialization): - sigs = list_signals(f) | list_special_ios(f, True, True, True) - special_outs = list_special_ios(f, False, True, True) - inouts = list_special_ios(f, False, False, True) - targets = list_targets(f) | special_outs - wires = _list_comb_wires(f) | special_outs - r = "module " + name + "(\n" - firstp = True - for sig in sorted(ios, key=lambda x: x.duid): - if not firstp: - r += ",\n" - firstp = False - if sig in inouts: - r += "\tinout " + _printsig(ns, sig) - elif sig in targets: - if sig in wires: - r += "\toutput " + _printsig(ns, sig) - else: - r += "\toutput reg " + _printsig(ns, sig) - else: - r += "\tinput " + _printsig(ns, sig) - r += "\n);\n\n" - for sig in sorted(sigs - ios, key=lambda x: x.duid): - if sig in wires: - r += "wire " + _printsig(ns, sig) + ";\n" - else: - if reg_initialization: - r += "reg " + _printsig(ns, sig) + " = " + _printexpr(ns, sig.reset)[0] + ";\n" - else: - r += "reg " + _printsig(ns, sig) + ";\n" - r += "\n" - return r - - -def _printcomb(f, ns, - display_run, - dummy_signal, - blocking_assign): - r = "" - if f.comb: - if dummy_signal: - # Generate a dummy event to get the simulator - # to run the combinatorial process once at the beginning. - syn_off = "// synthesis translate_off\n" - syn_on = "// synthesis translate_on\n" - dummy_s = Signal(name_override="dummy_s") - r += syn_off - r += "reg " + _printsig(ns, dummy_s) + ";\n" - r += "initial " + ns.get_name(dummy_s) + " <= 1'd0;\n" - r += syn_on - - groups = group_by_targets(f.comb) - - for n, g in enumerate(groups): - if len(g[1]) == 1 and isinstance(g[1][0], _Assign): - r += "assign " + _printnode(ns, _AT_BLOCKING, 0, g[1][0]) - else: - if dummy_signal: - dummy_d = Signal(name_override="dummy_d") - r += "\n" + syn_off - r += "reg " + _printsig(ns, dummy_d) + ";\n" - r += syn_on - - r += "always @(*) begin\n" - if display_run: - r += "\t$display(\"Running comb block #" + str(n) + "\");\n" - if blocking_assign: - for t in g[0]: - r += "\t" + ns.get_name(t) + " = " + _printexpr(ns, t.reset)[0] + ";\n" - r += _printnode(ns, _AT_BLOCKING, 1, g[1]) - else: - for t in g[0]: - r += "\t" + ns.get_name(t) + " <= " + _printexpr(ns, t.reset)[0] + ";\n" - r += _printnode(ns, _AT_NONBLOCKING, 1, g[1]) - if dummy_signal: - r += syn_off - r += "\t" + ns.get_name(dummy_d) + " <= " + ns.get_name(dummy_s) + ";\n" - r += syn_on - r += "end\n" - r += "\n" - return r - - -def _printsync(f, ns): - r = "" - for k, v in sorted(f.sync.items(), key=itemgetter(0)): - r += "always @(posedge " + ns.get_name(f.clock_domains[k].clk) + ") begin\n" - r += _printnode(ns, _AT_SIGNAL, 1, v) - r += "end\n\n" - return r - - -def _call_special_classmethod(overrides, obj, method, *args, **kwargs): - cl = obj.__class__ - if cl in overrides: - cl = overrides[cl] - if hasattr(cl, method): - return getattr(cl, method)(obj, *args, **kwargs) - else: - return None - - -def _lower_specials_step(overrides, specials): - f = _Fragment() - lowered_specials = set() - for special in sorted(specials, key=lambda x: x.duid): - impl = _call_special_classmethod(overrides, special, "lower") - if impl is not None: - f += impl.get_fragment() - lowered_specials.add(special) - return f, lowered_specials - - -def _can_lower(overrides, specials): - for special in specials: - cl = special.__class__ - if cl in overrides: - cl = overrides[cl] - if hasattr(cl, "lower"): - return True - return False - - -def _lower_specials(overrides, specials): - f, lowered_specials = _lower_specials_step(overrides, specials) - while _can_lower(overrides, f.specials): - f2, lowered_specials2 = _lower_specials_step(overrides, f.specials) - f += f2 - lowered_specials |= lowered_specials2 - f.specials -= lowered_specials2 - return f, lowered_specials - - -def _printspecials(overrides, specials, ns, add_data_file): - r = "" - for special in sorted(specials, key=lambda x: x.duid): - pr = _call_special_classmethod(overrides, special, "emit_verilog", ns, add_data_file) - if pr is None: - raise NotImplementedError("Special " + str(special) + " failed to implement emit_verilog") - r += pr - return r - - -def convert(f, ios=None, name="top", - special_overrides=dict(), - create_clock_domains=True, - display_run=False, asic_syntax=False): - r = ConvOutput() - if not isinstance(f, _Fragment): - f = f.get_fragment() - if ios is None: - ios = set() - - for cd_name in sorted(list_clock_domains(f)): - try: - f.clock_domains[cd_name] - except KeyError: - if create_clock_domains: - cd = ClockDomain(cd_name) - f.clock_domains.append(cd) - ios |= {cd.clk, cd.rst} - else: - raise KeyError("Unresolved clock domain: '"+cd_name+"'") - - f = lower_complex_slices(f) - insert_resets(f) - f = lower_basics(f) - fs, lowered_specials = _lower_specials(special_overrides, f.specials) - f += lower_basics(fs) - - ns = build_namespace(list_signals(f) \ - | list_special_ios(f, True, True, True) \ - | ios, _reserved_keywords) - ns.clock_domains = f.clock_domains - r.ns = ns - - src = "/* Machine-generated using Migen */\n" - src += _printheader(f, ios, name, ns, - reg_initialization=not asic_syntax) - src += _printcomb(f, ns, - display_run=display_run, - dummy_signal=not asic_syntax, - blocking_assign=asic_syntax) - src += _printsync(f, ns) - src += _printspecials(special_overrides, f.specials - lowered_specials, ns, r.add_data_file) - src += "endmodule\n" - r.set_main_source(src) - - return r diff --git a/migen/fhdl/visit.py b/migen/fhdl/visit.py deleted file mode 100644 index dd3ebbd7..00000000 --- a/migen/fhdl/visit.py +++ /dev/null @@ -1,202 +0,0 @@ -from copy import copy - -from migen.fhdl.structure import * -from migen.fhdl.structure import (_Operator, _Slice, _Assign, _ArrayProxy, - _Fragment) - - -class NodeVisitor: - def visit(self, node): - if isinstance(node, Constant): - self.visit_Constant(node) - elif isinstance(node, Signal): - self.visit_Signal(node) - elif isinstance(node, ClockSignal): - self.visit_ClockSignal(node) - elif isinstance(node, ResetSignal): - self.visit_ResetSignal(node) - elif isinstance(node, _Operator): - self.visit_Operator(node) - elif isinstance(node, _Slice): - self.visit_Slice(node) - elif isinstance(node, Cat): - self.visit_Cat(node) - elif isinstance(node, Replicate): - self.visit_Replicate(node) - elif isinstance(node, _Assign): - self.visit_Assign(node) - elif isinstance(node, If): - self.visit_If(node) - elif isinstance(node, Case): - self.visit_Case(node) - elif isinstance(node, _Fragment): - self.visit_Fragment(node) - elif isinstance(node, (list, tuple)): - self.visit_statements(node) - elif isinstance(node, dict): - self.visit_clock_domains(node) - elif isinstance(node, _ArrayProxy): - self.visit_ArrayProxy(node) - elif node is not None: - self.visit_unknown(node) - - def visit_Constant(self, node): - pass - - def visit_Signal(self, node): - pass - - def visit_ClockSignal(self, node): - pass - - def visit_ResetSignal(self, node): - pass - - def visit_Operator(self, node): - for o in node.operands: - self.visit(o) - - def visit_Slice(self, node): - self.visit(node.value) - - def visit_Cat(self, node): - for e in node.l: - self.visit(e) - - def visit_Replicate(self, node): - self.visit(node.v) - - def visit_Assign(self, node): - self.visit(node.l) - self.visit(node.r) - - def visit_If(self, node): - self.visit(node.cond) - self.visit(node.t) - self.visit(node.f) - - def visit_Case(self, node): - self.visit(node.test) - for v, statements in node.cases.items(): - self.visit(statements) - - def visit_Fragment(self, node): - self.visit(node.comb) - self.visit(node.sync) - - def visit_statements(self, node): - for statement in node: - self.visit(statement) - - def visit_clock_domains(self, node): - for clockname, statements in node.items(): - self.visit(statements) - - def visit_ArrayProxy(self, node): - for choice in node.choices: - self.visit(choice) - self.visit(node.key) - - def visit_unknown(self, node): - pass - - -# Default methods always copy the node, except for: -# - Signals, ClockSignals and ResetSignals -# - Unknown objects -# - All fragment fields except comb and sync -# In those cases, the original node is returned unchanged. -class NodeTransformer: - def visit(self, node): - if isinstance(node, Constant): - return self.visit_Constant(node) - elif isinstance(node, Signal): - return self.visit_Signal(node) - elif isinstance(node, ClockSignal): - return self.visit_ClockSignal(node) - elif isinstance(node, ResetSignal): - return self.visit_ResetSignal(node) - elif isinstance(node, _Operator): - return self.visit_Operator(node) - elif isinstance(node, _Slice): - return self.visit_Slice(node) - elif isinstance(node, Cat): - return self.visit_Cat(node) - elif isinstance(node, Replicate): - return self.visit_Replicate(node) - elif isinstance(node, _Assign): - return self.visit_Assign(node) - elif isinstance(node, If): - return self.visit_If(node) - elif isinstance(node, Case): - return self.visit_Case(node) - elif isinstance(node, _Fragment): - return self.visit_Fragment(node) - elif isinstance(node, (list, tuple)): - return self.visit_statements(node) - elif isinstance(node, dict): - return self.visit_clock_domains(node) - elif isinstance(node, _ArrayProxy): - return self.visit_ArrayProxy(node) - elif node is not None: - return self.visit_unknown(node) - else: - return None - - def visit_Constant(self, node): - return node - - def visit_Signal(self, node): - return node - - def visit_ClockSignal(self, node): - return node - - def visit_ResetSignal(self, node): - return node - - def visit_Operator(self, node): - return _Operator(node.op, [self.visit(o) for o in node.operands]) - - def visit_Slice(self, node): - return _Slice(self.visit(node.value), node.start, node.stop) - - def visit_Cat(self, node): - return Cat(*[self.visit(e) for e in node.l]) - - def visit_Replicate(self, node): - return Replicate(self.visit(node.v), node.n) - - def visit_Assign(self, node): - return _Assign(self.visit(node.l), self.visit(node.r)) - - def visit_If(self, node): - r = If(self.visit(node.cond)) - r.t = self.visit(node.t) - r.f = self.visit(node.f) - return r - - def visit_Case(self, node): - cases = dict((v, self.visit(statements)) for v, statements in node.cases.items()) - r = Case(self.visit(node.test), cases) - return r - - def visit_Fragment(self, node): - r = copy(node) - r.comb = self.visit(node.comb) - r.sync = self.visit(node.sync) - return r - - # NOTE: this will always return a list, even if node is a tuple - def visit_statements(self, node): - return [self.visit(statement) for statement in node] - - def visit_clock_domains(self, node): - return dict((clockname, self.visit(statements)) for clockname, statements in node.items()) - - def visit_ArrayProxy(self, node): - return _ArrayProxy([self.visit(choice) for choice in node.choices], - self.visit(node.key)) - - def visit_unknown(self, node): - return node diff --git a/migen/genlib/__init__.py b/migen/genlib/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/migen/genlib/coding.py b/migen/genlib/coding.py deleted file mode 100644 index 6327b388..00000000 --- a/migen/genlib/coding.py +++ /dev/null @@ -1,98 +0,0 @@ -""" -Encoders and decoders between binary and one-hot representation -""" - -from migen.fhdl.structure import * -from migen.fhdl.module import Module - - -class Encoder(Module): - """Encode one-hot to binary - - If `n` is low, the `o` th bit in `i` is asserted, else none or - multiple bits are asserted. - - Parameters - ---------- - width : int - Bit width of the input - - Attributes - ---------- - i : Signal(width), in - One-hot input - o : Signal(max=width), out - Encoded binary - n : Signal(1), out - Invalid, either none or multiple input bits are asserted - """ - def __init__(self, width): - self.i = Signal(width) # one-hot - self.o = Signal(max=max(2, width)) # binary - self.n = Signal() # invalid: none or multiple - act = dict((1< 0: - state = name - for i in range(delay): - if i == delay - 1: - next_state = target - else: - next_state = AnonymousState() - self.act(state, NextState(next_state)) - state = next_state - else: - self.state_aliases[name] = target - - def ongoing(self, state): - is_ongoing = Signal() - self.act(state, is_ongoing.eq(1)) - return is_ongoing - - def _get_signal(self, d, state): - if state not in self.actions: - self.actions[state] = [] - try: - return d[state] - except KeyError: - is_el = Signal() - d[state] = is_el - return is_el - - def before_entering(self, state): - return self._get_signal(self.before_entering_signals, state) - - def before_leaving(self, state): - return self._get_signal(self.before_leaving_signals, state) - - def after_entering(self, state): - signal = self._get_signal(self.after_entering_signals, state) - self.sync += signal.eq(self.before_entering(state)) - return signal - - def after_leaving(self, state): - signal = self._get_signal(self.after_leaving_signals, state) - self.sync += signal.eq(self.before_leaving(state)) - return signal - - def do_finalize(self): - nstates = len(self.actions) - self.encoding = dict((s, n) for n, s in enumerate(self.actions.keys())) - self.state = Signal(max=nstates, reset=self.encoding[self.reset_state]) - self.next_state = Signal(max=nstates) - - ln = _LowerNext(self.next_state, self.encoding, self.state_aliases) - cases = dict((self.encoding[k], ln.visit(v)) for k, v in self.actions.items() if v) - self.comb += [ - self.next_state.eq(self.state), - Case(self.state, cases).makedefault(self.encoding[self.reset_state]) - ] - self.sync += self.state.eq(self.next_state) - for register, next_value_ce, next_value in ln.registers: - self.sync += If(next_value_ce, register.eq(next_value)) - - # drive entering/leaving signals - for state, signal in self.before_leaving_signals.items(): - encoded = self.encoding[state] - self.comb += signal.eq((self.state == encoded) & ~(self.next_state == encoded)) - if self.reset_state in self.after_entering_signals: - self.after_entering_signals[self.reset_state].reset = 1 - for state, signal in self.before_entering_signals.items(): - encoded = self.encoding[state] - self.comb += signal.eq(~(self.state == encoded) & (self.next_state == encoded)) diff --git a/migen/genlib/io.py b/migen/genlib/io.py deleted file mode 100644 index fc930125..00000000 --- a/migen/genlib/io.py +++ /dev/null @@ -1,96 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module -from migen.fhdl.specials import Special - - -class DifferentialInput(Special): - def __init__(self, i_p, i_n, o): - Special.__init__(self) - self.i_p = wrap(i_p) - self.i_n = wrap(i_n) - self.o = wrap(o) - - def iter_expressions(self): - yield self, "i_p", SPECIAL_INPUT - yield self, "i_n", SPECIAL_INPUT - yield self, "o", SPECIAL_OUTPUT - - @staticmethod - def lower(dr): - raise NotImplementedError("Attempted to use a differential input, but platform does not support them") - - -class DifferentialOutput(Special): - def __init__(self, i, o_p, o_n): - Special.__init__(self) - self.i = wrap(i) - self.o_p = wrap(o_p) - self.o_n = wrap(o_n) - - def iter_expressions(self): - yield self, "i", SPECIAL_INPUT - yield self, "o_p", SPECIAL_OUTPUT - yield self, "o_n", SPECIAL_OUTPUT - - @staticmethod - def lower(dr): - raise NotImplementedError("Attempted to use a differential output, but platform does not support them") - - -class CRG(Module): - def __init__(self, clk, rst=0): - self.clock_domains.cd_sys = ClockDomain() - self.clock_domains.cd_por = ClockDomain(reset_less=True) - - if hasattr(clk, "p"): - clk_se = Signal() - self.specials += DifferentialInput(clk.p, clk.n, clk_se) - clk = clk_se - - # Power on Reset (vendor agnostic) - int_rst = Signal(reset=1) - self.sync.por += int_rst.eq(rst) - self.comb += [ - self.cd_sys.clk.eq(clk), - self.cd_por.clk.eq(clk), - self.cd_sys.rst.eq(int_rst) - ] - - -class DDRInput(Special): - def __init__(self, i, o1, o2, clk=ClockSignal()): - Special.__init__(self) - self.i = wrap(i) - self.o1 = wrap(o1) - self.o2 = wrap(o2) - self.clk = wrap(clk) - - def iter_expressions(self): - yield self, "i", SPECIAL_INPUT - yield self, "o1", SPECIAL_OUTPUT - yield self, "o2", SPECIAL_OUTPUT - yield self, "clk", SPECIAL_INPUT - - @staticmethod - def lower(dr): - raise NotImplementedError("Attempted to use a DDR input, but platform does not support them") - - -class DDROutput(Special): - def __init__(self, i1, i2, o, clk=ClockSignal()): - Special.__init__(self) - self.i1 = i1 - self.i2 = i2 - self.o = o - self.clk = clk - - def iter_expressions(self): - yield self, "i1", SPECIAL_INPUT - yield self, "i2", SPECIAL_INPUT - yield self, "o", SPECIAL_OUTPUT - yield self, "clk", SPECIAL_INPUT - - @staticmethod - def lower(dr): - raise NotImplementedError("Attempted to use a DDR output, but platform does not support them") - diff --git a/migen/genlib/record.py b/migen/genlib/record.py deleted file mode 100644 index bf6aa619..00000000 --- a/migen/genlib/record.py +++ /dev/null @@ -1,179 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.tracer import get_obj_var_name - -from functools import reduce -from operator import or_ - - -(DIR_NONE, DIR_S_TO_M, DIR_M_TO_S) = range(3) - -# Possible layout elements: -# 1. (name, size) -# 2. (name, size, direction) -# 3. (name, sublayout) -# size can be an int, or a (int, bool) tuple for signed numbers -# sublayout must be a list - - -def set_layout_parameters(layout, **layout_dict): - def resolve(p): - if isinstance(p, str): - try: - return layout_dict[p] - except KeyError: - return p - else: - return p - - r = [] - for f in layout: - if isinstance(f[1], (int, tuple, str)): # cases 1/2 - if len(f) == 3: - r.append((f[0], resolve(f[1]), f[2])) - else: - r.append((f[0], resolve(f[1]))) - elif isinstance(f[1], list): # case 3 - r.append((f[0], set_layout_parameters(f[1], **layout_dict))) - else: - raise TypeError - return r - - -def layout_len(layout): - r = 0 - for f in layout: - if isinstance(f[1], (int, tuple)): # cases 1/2 - if len(f) == 3: - fname, fsize, fdirection = f - else: - fname, fsize = f - elif isinstance(f[1], list): # case 3 - fname, fsublayout = f - fsize = layout_len(fsublayout) - else: - raise TypeError - if isinstance(fsize, tuple): - r += fsize[0] - else: - r += fsize - return r - - -def layout_get(layout, name): - for f in layout: - if f[0] == name: - return f - raise KeyError(name) - - -def layout_partial(layout, *elements): - r = [] - for path in elements: - path_s = path.split("/") - last = path_s.pop() - copy_ref = layout - insert_ref = r - for hop in path_s: - name, copy_ref = layout_get(copy_ref, hop) - try: - name, insert_ref = layout_get(insert_ref, hop) - except KeyError: - new_insert_ref = [] - insert_ref.append((hop, new_insert_ref)) - insert_ref = new_insert_ref - insert_ref.append(layout_get(copy_ref, last)) - return r - - -class Record: - def __init__(self, layout, name=None): - self.name = get_obj_var_name(name, "") - self.layout = layout - - if self.name: - prefix = self.name + "_" - else: - prefix = "" - for f in self.layout: - if isinstance(f[1], (int, tuple)): # cases 1/2 - if(len(f) == 3): - fname, fsize, fdirection = f - else: - fname, fsize = f - finst = Signal(fsize, name=prefix + fname) - elif isinstance(f[1], list): # case 3 - fname, fsublayout = f - finst = Record(fsublayout, prefix + fname) - else: - raise TypeError - setattr(self, fname, finst) - - def eq(self, other): - return [getattr(self, f[0]).eq(getattr(other, f[0])) - for f in self.layout if hasattr(other, f[0])] - - def iter_flat(self): - for f in self.layout: - e = getattr(self, f[0]) - if isinstance(e, Signal): - if len(f) == 3: - yield e, f[2] - else: - yield e, DIR_NONE - elif isinstance(e, Record): - yield from e.iter_flat() - else: - raise TypeError - - def flatten(self): - return [signal for signal, direction in self.iter_flat()] - - def raw_bits(self): - return Cat(*self.flatten()) - - def connect(self, *slaves, leave_out=set()): - if isinstance(leave_out, str): - leave_out = {leave_out} - r = [] - for f in self.layout: - field = f[0] - if field not in leave_out: - self_e = getattr(self, field) - if isinstance(self_e, Signal): - direction = f[2] - if direction == DIR_M_TO_S: - r += [getattr(slave, field).eq(self_e) for slave in slaves] - elif direction == DIR_S_TO_M: - r.append(self_e.eq(reduce(or_, [getattr(slave, field) for slave in slaves]))) - else: - raise TypeError - else: - for slave in slaves: - r += self_e.connect(getattr(slave, field), leave_out=leave_out) - return r - - def connect_flat(self, *slaves): - r = [] - iter_slaves = [slave.iter_flat() for slave in slaves] - for m_signal, m_direction in self.iter_flat(): - if m_direction == DIR_M_TO_S: - for iter_slave in iter_slaves: - s_signal, s_direction = next(iter_slave) - assert(s_direction == DIR_M_TO_S) - r.append(s_signal.eq(m_signal)) - elif m_direction == DIR_S_TO_M: - s_signals = [] - for iter_slave in iter_slaves: - s_signal, s_direction = next(iter_slave) - assert(s_direction == DIR_S_TO_M) - s_signals.append(s_signal) - r.append(m_signal.eq(reduce(or_, s_signals))) - else: - raise TypeError - return r - - def __len__(self): - return layout_len(self.layout) - - def __repr__(self): - return "" diff --git a/migen/genlib/resetsync.py b/migen/genlib/resetsync.py deleted file mode 100644 index db936900..00000000 --- a/migen/genlib/resetsync.py +++ /dev/null @@ -1,18 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.specials import Special - - -class AsyncResetSynchronizer(Special): - def __init__(self, cd, async_reset): - Special.__init__(self) - self.cd = cd - self.async_reset = wrap(async_reset) - - def iter_expressions(self): - yield self.cd, "clk", SPECIAL_INPUT - yield self.cd, "rst", SPECIAL_OUTPUT - yield self, "async_reset", SPECIAL_INPUT - - @staticmethod - def lower(dr): - raise NotImplementedError("Attempted to use a reset synchronizer, but platform does not support them") diff --git a/migen/genlib/roundrobin.py b/migen/genlib/roundrobin.py deleted file mode 100644 index 87ac5bb6..00000000 --- a/migen/genlib/roundrobin.py +++ /dev/null @@ -1,41 +0,0 @@ -from migen.fhdl.structure import * -from migen.fhdl.module import Module - - -(SP_WITHDRAW, SP_CE) = range(2) - - -class RoundRobin(Module): - def __init__(self, n, switch_policy=SP_WITHDRAW): - self.request = Signal(n) - self.grant = Signal(max=max(2, n)) - self.switch_policy = switch_policy - if self.switch_policy == SP_CE: - self.ce = Signal() - - ### - - if n > 1: - cases = {} - for i in range(n): - switch = [] - for j in reversed(range(i+1, i+n)): - t = j % n - switch = [ - If(self.request[t], - self.grant.eq(t) - ).Else( - *switch - ) - ] - if self.switch_policy == SP_WITHDRAW: - case = [If(~self.request[i], *switch)] - else: - case = switch - cases[i] = case - statement = Case(self.grant, cases) - if self.switch_policy == SP_CE: - statement = If(self.ce, statement) - self.sync += statement - else: - self.comb += self.grant.eq(0) diff --git a/migen/sim/__init__.py b/migen/sim/__init__.py deleted file mode 100644 index d99780b8..00000000 --- a/migen/sim/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from migen.sim.core import Simulator, run_simulation diff --git a/migen/sim/core.py b/migen/sim/core.py deleted file mode 100644 index f89cd02c..00000000 --- a/migen/sim/core.py +++ /dev/null @@ -1,335 +0,0 @@ -import operator -import collections -import inspect - -from migen.fhdl.structure import * -from migen.fhdl.structure import (_Value, _Statement, - _Operator, _Slice, _ArrayProxy, - _Assign, _Fragment) -from migen.fhdl.bitcontainer import value_bits_sign -from migen.fhdl.tools import list_signals, list_targets, insert_resets -from migen.fhdl.simplify import MemoryToArray -from migen.fhdl.specials import _MemoryLocation -from migen.sim.vcd import VCDWriter, DummyVCDWriter - - -class ClockState: - def __init__(self, high, half_period, time_before_trans): - self.high = high - self.half_period = half_period - self.time_before_trans = time_before_trans - - -class TimeManager: - def __init__(self, description): - self.clocks = dict() - - for k, period_phase in description.items(): - if isinstance(period_phase, tuple): - period, phase = period_phase - else: - period = period_phase - phase = 0 - half_period = period//2 - if phase >= half_period: - phase -= half_period - high = True - else: - high = False - self.clocks[k] = ClockState(high, half_period, half_period - phase) - - def tick(self): - rising = set() - falling = set() - dt = min(cs.time_before_trans for cs in self.clocks.values()) - for k, cs in self.clocks.items(): - if cs.time_before_trans == dt: - cs.high = not cs.high - if cs.high: - rising.add(k) - else: - falling.add(k) - cs.time_before_trans -= dt - if not cs.time_before_trans: - cs.time_before_trans += cs.half_period - return dt, rising, falling - - -str2op = { - "~": operator.invert, - "+": operator.add, - "-": operator.sub, - "*": operator.mul, - - ">>>": operator.rshift, - "<<<": operator.lshift, - - "&": operator.and_, - "^": operator.xor, - "|": operator.or_, - - "<": operator.lt, - "<=": operator.le, - "==": operator.eq, - "!=": operator.ne, - ">": operator.gt, - ">=": operator.ge, -} - - -def _truncate(value, nbits, signed): - value = value & (2**nbits - 1) - if signed and (value & 2**(nbits - 1)): - value -= 2**nbits - return value - - -class Evaluator: - def __init__(self, clock_domains, replaced_memories): - self.clock_domains = clock_domains - self.replaced_memories = replaced_memories - self.signal_values = dict() - self.modifications = dict() - - def commit(self): - r = set() - for k, v in self.modifications.items(): - if k not in self.signal_values or self.signal_values[k] != v: - self.signal_values[k] = v - r.add(k) - self.modifications.clear() - return r - - def eval(self, node, postcommit=False): - if isinstance(node, Constant): - return node.value - elif isinstance(node, Signal): - if postcommit: - try: - return self.modifications[node] - except KeyError: - pass - try: - return self.signal_values[node] - except KeyError: - return node.reset.value - elif isinstance(node, _Operator): - operands = [self.eval(o, postcommit) for o in node.operands] - if node.op == "-": - if len(operands) == 1: - return -operands[0] - else: - return operands[0] - operands[1] - elif node.op == "m": - return operands[1] if operands[0] else operands[2] - else: - return str2op[node.op](*operands) - elif isinstance(node, _Slice): - v = self.eval(node.value, postcommit) - idx = range(node.start, node.stop) - return sum(((v >> i) & 1) << j for j, i in enumerate(idx)) - elif isinstance(node, Cat): - shift = 0 - r = 0 - for element in node.l: - nbits = len(element) - # make value always positive - r |= (self.eval(element, postcommit) & (2**nbits-1)) << shift - shift += nbits - return r - elif isinstance(node, _ArrayProxy): - return self.eval(node.choices[self.eval(node.key, postcommit)], - postcommit) - elif isinstance(node, _MemoryLocation): - array = self.replaced_memories[node.memory] - return self.eval(array[self.eval(node.index, postcommit)], postcommit) - elif isinstance(node, ClockSignal): - return self.eval(self.clock_domains[node.cd].clk, postcommit) - elif isinstance(node, ResetSignal): - rst = self.clock_domains[node.cd].rst - if rst is None: - if node.allow_reset_less: - return 0 - else: - raise ValueError("Attempted to get reset signal of resetless" - " domain '{}'".format(node.cd)) - else: - return self.eval(rst, postcommit) - else: - raise NotImplementedError - - def assign(self, node, value): - if isinstance(node, Signal): - assert not node.variable - self.modifications[node] = _truncate(value, - node.nbits, node.signed) - elif isinstance(node, Cat): - for element in node.l: - nbits = len(element) - self.assign(element, value & (2**nbits-1)) - value >>= nbits - elif isinstance(node, _Slice): - full_value = self.eval(node.value, True) - # clear bits assigned to by the slice - full_value &= ~((2**node.stop-1) - (2**node.start-1)) - # set them to the new value - value &= 2**(node.stop - node.start)-1 - full_value |= value << node.start - self.assign(node.value, full_value) - elif isinstance(node, _ArrayProxy): - self.assign(node.choices[self.eval(node.key)], value) - elif isinstance(node, _MemoryLocation): - array = self.replaced_memories[node.memory] - self.assign(array[self.eval(node.index)], value) - else: - raise NotImplementedError - - def execute(self, statements): - for s in statements: - if isinstance(s, _Assign): - self.assign(s.l, self.eval(s.r)) - elif isinstance(s, If): - if self.eval(s.cond) & (2**len(s.cond) - 1): - self.execute(s.t) - else: - self.execute(s.f) - elif isinstance(s, Case): - nbits, signed = value_bits_sign(s.test) - test = _truncate(self.eval(s.test), nbits, signed) - found = False - for k, v in s.cases.items(): - if isinstance(k, Constant) and k.value == test: - self.execute(v) - found = True - break - if not found and "default" in s.cases: - self.execute(s.cases["default"]) - elif isinstance(s, collections.Iterable): - self.execute(s) - else: - raise NotImplementedError - - -# TODO: instances via Iverilog/VPI -class Simulator: - def __init__(self, fragment_or_module, generators, clocks={"sys": 10}, vcd_name=None): - if isinstance(fragment_or_module, _Fragment): - self.fragment = fragment_or_module - else: - self.fragment = fragment_or_module.get_fragment() - if not isinstance(generators, dict): - generators = {"sys": generators} - self.generators = dict() - for k, v in generators.items(): - if (isinstance(v, collections.Iterable) - and not inspect.isgenerator(v)): - self.generators[k] = list(v) - else: - self.generators[k] = [v] - - self.time = TimeManager(clocks) - for clock in clocks.keys(): - if clock not in self.fragment.clock_domains: - cd = ClockDomain(name=clock, reset_less=True) - cd.clk.reset = C(self.time.clocks[clock].high) - self.fragment.clock_domains.append(cd) - - mta = MemoryToArray() - mta.transform_fragment(None, self.fragment) - insert_resets(self.fragment) - # comb signals return to their reset value if nothing assigns them - self.fragment.comb[0:0] = [s.eq(s.reset) - for s in list_targets(self.fragment.comb)] - self.evaluator = Evaluator(self.fragment.clock_domains, - mta.replacements) - - if vcd_name is None: - self.vcd = DummyVCDWriter() - else: - signals = list_signals(self.fragment) - for cd in self.fragment.clock_domains: - signals.add(cd.clk) - if cd.rst is not None: - signals.add(cd.rst) - for memory_array in mta.replacements.values(): - signals |= set(memory_array) - signals = sorted(signals, key=lambda x: x.duid) - self.vcd = VCDWriter(vcd_name, signals) - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - def close(self): - self.vcd.close() - - def _commit_and_comb_propagate(self): - # TODO: optimize - all_modified = set() - modified = self.evaluator.commit() - all_modified |= modified - while modified: - self.evaluator.execute(self.fragment.comb) - modified = self.evaluator.commit() - all_modified |= modified - for signal in all_modified: - self.vcd.set(signal, self.evaluator.signal_values[signal]) - - def _evalexec_nested_lists(self, x): - if isinstance(x, list): - return [self._evalexec_nested_lists(e) for e in x] - elif isinstance(x, _Value): - return self.evaluator.eval(x) - elif isinstance(x, _Statement): - self.evaluator.execute([x]) - return None - else: - raise ValueError - - def _process_generators(self, cd): - exhausted = [] - for generator in self.generators[cd]: - reply = None - while True: - try: - request = generator.send(reply) - if request is None: - break # next cycle - else: - reply = self._evalexec_nested_lists(request) - except StopIteration: - exhausted.append(generator) - break - for generator in exhausted: - self.generators[cd].remove(generator) - - def _continue_simulation(self): - # TODO: passive generators - return any(self.generators.values()) - - def run(self): - self.evaluator.execute(self.fragment.comb) - self._commit_and_comb_propagate() - - while True: - dt, rising, falling = self.time.tick() - self.vcd.delay(dt) - for cd in rising: - self.evaluator.assign(self.fragment.clock_domains[cd].clk, 1) - if cd in self.fragment.sync: - self.evaluator.execute(self.fragment.sync[cd]) - if cd in self.generators: - self._process_generators(cd) - for cd in falling: - self.evaluator.assign(self.fragment.clock_domains[cd].clk, 0) - self._commit_and_comb_propagate() - - if not self._continue_simulation(): - break - - -def run_simulation(*args, **kwargs): - with Simulator(*args, **kwargs) as s: - s.run() diff --git a/migen/test/__init__.py b/migen/test/__init__.py deleted file mode 100644 index e69de29b..00000000 diff --git a/migen/test/support.py b/migen/test/support.py deleted file mode 100644 index c1bb4697..00000000 --- a/migen/test/support.py +++ /dev/null @@ -1,13 +0,0 @@ -from migen import * -from migen.fhdl import verilog - - -class SimCase: - def setUp(self, *args, **kwargs): - self.tb = self.TestBench(*args, **kwargs) - - def test_to_verilog(self): - verilog.convert(self.tb) - - def run_with(self, generator): - run_simulation(self.tb, generator) diff --git a/migen/test/test_coding.py b/migen/test/test_coding.py deleted file mode 100644 index 64cfb6fd..00000000 --- a/migen/test/test_coding.py +++ /dev/null @@ -1,113 +0,0 @@ -import unittest - -from migen import * -from migen.genlib.coding import * - -from migen.test.support import SimCase - - -class EncCase(SimCase, unittest.TestCase): - class TestBench(Module): - def __init__(self): - self.submodules.dut = Encoder(8) - - def test_sizes(self): - self.assertEqual(len(self.tb.dut.i), 8) - self.assertEqual(len(self.tb.dut.o), 3) - self.assertEqual(len(self.tb.dut.n), 1) - - def test_run_sequence(self): - seq = list(range(1<<8)) - def gen(): - for _ in range(256): - if seq: - yield self.tb.dut.i.eq(seq.pop(0)) - if (yield self.tb.dut.n): - self.assertNotIn((yield self.tb.dut.i), [1< 0: - self.assertEqual(i & 1<<(o - 1), 0) - self.assertGreaterEqual(i, 1< 0: - self.assertEqual(i & 1<<(o - 1), 0) - self.assertGreaterEqual(i, 1< q, - lambda p, q: p >= q, - lambda p, q: p < q, - lambda p, q: p <= q, - lambda p, q: p == q, - lambda p, q: p != q, - ] - self.vals = [] - for asign in 1, -1: - for bsign in 1, -1: - for f in comps: - r = Signal() - r0 = f(asign*self.a, bsign*self.b) - self.comb += r.eq(r0) - self.vals.append((asign, bsign, f, r, r0.op)) - - def test_comparisons(self): - def gen(): - for i in range(-4, 4): - yield self.tb.a.eq(i) - yield self.tb.b.eq(i) - a = yield self.tb.a - b = yield self.tb.b - for asign, bsign, f, r, op in self.tb.vals: - r, r0 = (yield r), f(asign*a, bsign*b) - self.assertEqual(r, int(r0), - "got {}, want {}*{} {} {}*{} = {}".format( - r, asign, a, op, bsign, b, r0)) - yield - self.run_with(gen()) diff --git a/migen/test/test_size.py b/migen/test/test_size.py deleted file mode 100644 index a44ae367..00000000 --- a/migen/test/test_size.py +++ /dev/null @@ -1,19 +0,0 @@ -import unittest - -from migen import * - - -def _same_slices(a, b): - return a.value is b.value and a.start == b.start and a.stop == b.stop - - -class SignalSizeCase(unittest.TestCase): - def setUp(self): - self.i = C(0xaa) - self.j = C(-127) - self.s = Signal((13, True)) - - def test_len(self): - self.assertEqual(len(self.s), 13) - self.assertEqual(len(self.i), 8) - self.assertEqual(len(self.j), 8) diff --git a/migen/test/test_sort.py b/migen/test/test_sort.py deleted file mode 100644 index acb9fa23..00000000 --- a/migen/test/test_sort.py +++ /dev/null @@ -1,30 +0,0 @@ -import unittest -from random import randrange - -from migen import * -from migen.genlib.sort import * - -from migen.test.support import SimCase - - -class BitonicCase(SimCase, unittest.TestCase): - class TestBench(Module): - def __init__(self): - self.submodules.dut = BitonicSort(8, 4, ascending=True) - - def test_sizes(self): - self.assertEqual(len(self.tb.dut.i), 8) - self.assertEqual(len(self.tb.dut.o), 8) - for i in range(8): - self.assertEqual(len(self.tb.dut.i[i]), 4) - self.assertEqual(len(self.tb.dut.o[i]), 4) - - def test_sort(self): - def gen(): - for repeat in range(20): - for i in self.tb.dut.i: - yield i.eq(randrange(1< 2014,2015 - -# assuming your xilinx toolchain lives in /opt/Xilinx, -# run `strace_tailor.sh /opt/Xilinx/ [synthesis script] [options]`, -# e.g. for the pipistrello target of misoc: -# strace_tailor.sh /opt/Xilinx/ ./make.py -t pipistrello build-bitstream -# then in your current directory, `opt/Xilinx/*` is the -# minimal toolchain required for this synthesis script run. - -PREFIX=$1 -shift -strace -e trace=file,process -f -o strace.log $@ -sed -n 's|^.*"\('"$PREFIX"'[^"]*\)".*$|\1|p' strace.log \ - | sort | uniq | xargs -d '\n' \ - cp --parent --no-dereference --preserve=all -t . -- 2.30.2